Merge pull request #39091 from deads2k/api-54-move-authn

Automatic merge from submit-queue

remove unneeded authenticator dependencies from genericapiserver

Refactors the authenticator options to remove unneeded dependencies.

@sttts
This commit is contained in:
Kubernetes Submit Queue 2016-12-22 06:48:24 -08:00 committed by GitHub
commit fc41bc6ec6
37 changed files with 876 additions and 628 deletions

View File

@ -21,7 +21,6 @@ go_library(
"//pkg/apis/autoscaling:go_default_library",
"//pkg/apis/batch:go_default_library",
"//pkg/apis/extensions:go_default_library",
"//pkg/apiserver/authenticator:go_default_library",
"//pkg/capabilities:go_default_library",
"//pkg/client/clientset_generated/internalclientset:go_default_library",
"//pkg/cloudprovider:go_default_library",
@ -30,8 +29,8 @@ go_library(
"//pkg/controller/serviceaccount:go_default_library",
"//pkg/generated/openapi:go_default_library",
"//pkg/genericapiserver:go_default_library",
"//pkg/genericapiserver/authorizer:go_default_library",
"//pkg/genericapiserver/filters:go_default_library",
"//pkg/kubeapiserver/authenticator:go_default_library",
"//pkg/master:go_default_library",
"//pkg/registry/cachesize:go_default_library",
"//pkg/runtime/schema:go_default_library",

View File

@ -19,6 +19,7 @@ go_library(
"//pkg/api:go_default_library",
"//pkg/api/validation:go_default_library",
"//pkg/genericapiserver/options:go_default_library",
"//pkg/kubeapiserver/options:go_default_library",
"//pkg/kubelet/client:go_default_library",
"//pkg/master/ports:go_default_library",
"//pkg/util/net:go_default_library",

View File

@ -24,6 +24,7 @@ import (
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/validation"
genericoptions "k8s.io/kubernetes/pkg/genericapiserver/options"
kubeoptions "k8s.io/kubernetes/pkg/kubeapiserver/options"
kubeletclient "k8s.io/kubernetes/pkg/kubelet/client"
"k8s.io/kubernetes/pkg/master/ports"
utilnet "k8s.io/kubernetes/pkg/util/net"
@ -40,8 +41,8 @@ type ServerRunOptions struct {
Etcd *genericoptions.EtcdOptions
SecureServing *genericoptions.SecureServingOptions
InsecureServing *genericoptions.ServingOptions
Authentication *genericoptions.BuiltInAuthenticationOptions
Authorization *genericoptions.BuiltInAuthorizationOptions
Authentication *kubeoptions.BuiltInAuthenticationOptions
Authorization *kubeoptions.BuiltInAuthorizationOptions
AllowPrivileged bool
EventTTL time.Duration
@ -62,8 +63,8 @@ func NewServerRunOptions() *ServerRunOptions {
Etcd: genericoptions.NewEtcdOptions(),
SecureServing: genericoptions.NewSecureServingOptions(),
InsecureServing: genericoptions.NewInsecureServingOptions(),
Authentication: genericoptions.NewBuiltInAuthenticationOptions().WithAll(),
Authorization: genericoptions.NewBuiltInAuthorizationOptions(),
Authentication: kubeoptions.NewBuiltInAuthenticationOptions().WithAll(),
Authorization: kubeoptions.NewBuiltInAuthorizationOptions(),
EventTTL: 1 * time.Hour,
MasterCount: 1,

View File

@ -41,7 +41,6 @@ import (
"k8s.io/kubernetes/pkg/apis/autoscaling"
"k8s.io/kubernetes/pkg/apis/batch"
"k8s.io/kubernetes/pkg/apis/extensions"
"k8s.io/kubernetes/pkg/apiserver/authenticator"
"k8s.io/kubernetes/pkg/capabilities"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
"k8s.io/kubernetes/pkg/cloudprovider"
@ -49,8 +48,8 @@ import (
serviceaccountcontroller "k8s.io/kubernetes/pkg/controller/serviceaccount"
generatedopenapi "k8s.io/kubernetes/pkg/generated/openapi"
"k8s.io/kubernetes/pkg/genericapiserver"
"k8s.io/kubernetes/pkg/genericapiserver/authorizer"
"k8s.io/kubernetes/pkg/genericapiserver/filters"
kubeauthenticator "k8s.io/kubernetes/pkg/kubeapiserver/authenticator"
"k8s.io/kubernetes/pkg/master"
"k8s.io/kubernetes/pkg/registry/cachesize"
"k8s.io/kubernetes/pkg/runtime/schema"
@ -108,7 +107,7 @@ func Run(s *options.ServerRunOptions) error {
if _, err := genericConfig.ApplySecureServingOptions(s.SecureServing); err != nil {
return fmt.Errorf("failed to configure https: %s", err)
}
if _, err = genericConfig.ApplyAuthenticationOptions(s.Authentication); err != nil {
if err = s.Authentication.Apply(genericConfig); err != nil {
return fmt.Errorf("failed to configure authentication: %s", err)
}
@ -218,7 +217,7 @@ func Run(s *options.ServerRunOptions) error {
// Default to the private server key for service account token signing
if len(s.Authentication.ServiceAccounts.KeyFiles) == 0 && s.SecureServing.ServerCert.CertKey.KeyFile != "" {
if authenticator.IsValidServiceAccountKeyFile(s.SecureServing.ServerCert.CertKey.KeyFile) {
if kubeauthenticator.IsValidServiceAccountKeyFile(s.SecureServing.ServerCert.CertKey.KeyFile) {
s.Authentication.ServiceAccounts.KeyFiles = []string{s.SecureServing.ServerCert.CertKey.KeyFile}
} else {
glog.Warning("No TLS key provided, service account token authentication disabled")
@ -236,7 +235,7 @@ func Run(s *options.ServerRunOptions) error {
authenticatorConfig.ServiceAccountTokenGetter = serviceaccountcontroller.NewGetterFromStorageInterface(storageConfig, storageFactory.ResourcePrefix(api.Resource("serviceaccounts")), storageFactory.ResourcePrefix(api.Resource("secrets")))
}
apiAuthenticator, securityDefinitions, err := authenticator.New(authenticatorConfig)
apiAuthenticator, securityDefinitions, err := authenticatorConfig.New()
if err != nil {
return fmt.Errorf("invalid Authentication Config: %v", err)
}
@ -261,7 +260,7 @@ func Run(s *options.ServerRunOptions) error {
sharedInformers := informers.NewSharedInformerFactory(nil, client, 10*time.Minute)
authorizationConfig := s.Authorization.ToAuthorizationConfig(sharedInformers)
apiAuthorizer, err := authorizer.NewAuthorizerFromAuthorizationConfig(authorizationConfig)
apiAuthorizer, err := authorizationConfig.New()
if err != nil {
return fmt.Errorf("invalid Authorization Config: %v", err)
}

View File

@ -25,7 +25,6 @@ go_library(
"//pkg/apis/componentconfig:go_default_library",
"//pkg/apis/componentconfig/v1alpha1:go_default_library",
"//pkg/apis/meta/v1:go_default_library",
"//pkg/apiserver/authenticator:go_default_library",
"//pkg/auth/authenticator:go_default_library",
"//pkg/auth/authorizer:go_default_library",
"//pkg/capabilities:go_default_library",
@ -46,6 +45,7 @@ go_library(
"//pkg/credentialprovider/aws:go_default_library",
"//pkg/credentialprovider/azure:go_default_library",
"//pkg/credentialprovider/gcp:go_default_library",
"//pkg/genericapiserver/authenticator:go_default_library",
"//pkg/genericapiserver/authorizer:go_default_library",
"//pkg/healthz:go_default_library",
"//pkg/kubelet:go_default_library",

View File

@ -22,12 +22,12 @@ import (
"reflect"
"k8s.io/kubernetes/pkg/apis/componentconfig"
apiserverauthenticator "k8s.io/kubernetes/pkg/apiserver/authenticator"
"k8s.io/kubernetes/pkg/auth/authenticator"
"k8s.io/kubernetes/pkg/auth/authorizer"
clientset "k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
authenticationclient "k8s.io/kubernetes/pkg/client/clientset_generated/clientset/typed/authentication/v1beta1"
authorizationclient "k8s.io/kubernetes/pkg/client/clientset_generated/clientset/typed/authorization/v1beta1"
apiserverauthenticator "k8s.io/kubernetes/pkg/genericapiserver/authenticator"
alwaysallowauthorizer "k8s.io/kubernetes/pkg/genericapiserver/authorizer"
apiserverauthorizer "k8s.io/kubernetes/pkg/genericapiserver/authorizer"
"k8s.io/kubernetes/pkg/kubelet/server"

View File

@ -21,6 +21,7 @@ go_library(
"//pkg/genericapiserver:go_default_library",
"//pkg/genericapiserver/authorizer:go_default_library",
"//pkg/genericapiserver/options:go_default_library",
"//pkg/kubeapiserver/options:go_default_library",
"//pkg/registry/generic:go_default_library",
"//pkg/runtime/schema:go_default_library",
"//pkg/storage/storagebackend:go_default_library",

View File

@ -27,6 +27,7 @@ import (
"k8s.io/kubernetes/pkg/genericapiserver"
"k8s.io/kubernetes/pkg/genericapiserver/authorizer"
genericoptions "k8s.io/kubernetes/pkg/genericapiserver/options"
kubeoptions "k8s.io/kubernetes/pkg/kubeapiserver/options"
"k8s.io/kubernetes/pkg/registry/generic"
"k8s.io/kubernetes/pkg/runtime/schema"
"k8s.io/kubernetes/pkg/storage/storagebackend"
@ -60,7 +61,7 @@ type ServerRunOptions struct {
Etcd *genericoptions.EtcdOptions
SecureServing *genericoptions.SecureServingOptions
InsecureServing *genericoptions.ServingOptions
Authentication *genericoptions.BuiltInAuthenticationOptions
Authentication *kubeoptions.BuiltInAuthenticationOptions
}
func NewServerRunOptions() *ServerRunOptions {
@ -69,7 +70,7 @@ func NewServerRunOptions() *ServerRunOptions {
Etcd: genericoptions.NewEtcdOptions(),
SecureServing: genericoptions.NewSecureServingOptions(),
InsecureServing: genericoptions.NewInsecureServingOptions(),
Authentication: genericoptions.NewBuiltInAuthenticationOptions().WithAll(),
Authentication: kubeoptions.NewBuiltInAuthenticationOptions().WithAll(),
}
s.InsecureServing.BindPort = InsecurePort
s.SecureServing.ServingOptions.BindPort = SecurePort
@ -107,7 +108,7 @@ func (serverOptions *ServerRunOptions) Run(stopCh <-chan struct{}) error {
if _, err := config.ApplySecureServingOptions(serverOptions.SecureServing); err != nil {
return fmt.Errorf("failed to configure https: %s", err)
}
if _, err := config.ApplyAuthenticationOptions(serverOptions.Authentication); err != nil {
if err := serverOptions.Authentication.Apply(config); err != nil {
return fmt.Errorf("failed to configure authentication: %s", err)
}

View File

@ -35,13 +35,11 @@ go_library(
"//pkg/apis/batch/install:go_default_library",
"//pkg/apis/extensions:go_default_library",
"//pkg/apis/extensions/install:go_default_library",
"//pkg/apiserver/authenticator:go_default_library",
"//pkg/client/clientset_generated/internalclientset:go_default_library",
"//pkg/cloudprovider/providers:go_default_library",
"//pkg/controller/informers:go_default_library",
"//pkg/generated/openapi:go_default_library",
"//pkg/genericapiserver:go_default_library",
"//pkg/genericapiserver/authorizer:go_default_library",
"//pkg/genericapiserver/filters:go_default_library",
"//pkg/registry/batch/job/etcd:go_default_library",
"//pkg/registry/cachesize:go_default_library",

View File

@ -16,6 +16,7 @@ go_library(
tags = ["automanaged"],
deps = [
"//pkg/genericapiserver/options:go_default_library",
"//pkg/kubeapiserver/options:go_default_library",
"//vendor:github.com/spf13/pflag",
],
)

View File

@ -21,6 +21,7 @@ import (
"time"
genericoptions "k8s.io/kubernetes/pkg/genericapiserver/options"
kubeoptions "k8s.io/kubernetes/pkg/kubeapiserver/options"
"github.com/spf13/pflag"
)
@ -31,8 +32,8 @@ type ServerRunOptions struct {
Etcd *genericoptions.EtcdOptions
SecureServing *genericoptions.SecureServingOptions
InsecureServing *genericoptions.ServingOptions
Authentication *genericoptions.BuiltInAuthenticationOptions
Authorization *genericoptions.BuiltInAuthorizationOptions
Authentication *kubeoptions.BuiltInAuthenticationOptions
Authorization *kubeoptions.BuiltInAuthorizationOptions
EventTTL time.Duration
}
@ -44,8 +45,8 @@ func NewServerRunOptions() *ServerRunOptions {
Etcd: genericoptions.NewEtcdOptions(),
SecureServing: genericoptions.NewSecureServingOptions(),
InsecureServing: genericoptions.NewInsecureServingOptions(),
Authentication: genericoptions.NewBuiltInAuthenticationOptions().WithAll(),
Authorization: genericoptions.NewBuiltInAuthorizationOptions(),
Authentication: kubeoptions.NewBuiltInAuthenticationOptions().WithAll(),
Authorization: kubeoptions.NewBuiltInAuthorizationOptions(),
EventTTL: 1 * time.Hour,
}

View File

@ -32,12 +32,10 @@ import (
"k8s.io/kubernetes/federation/cmd/federation-apiserver/app/options"
"k8s.io/kubernetes/pkg/admission"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/apiserver/authenticator"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
"k8s.io/kubernetes/pkg/controller/informers"
"k8s.io/kubernetes/pkg/generated/openapi"
"k8s.io/kubernetes/pkg/genericapiserver"
"k8s.io/kubernetes/pkg/genericapiserver/authorizer"
"k8s.io/kubernetes/pkg/genericapiserver/filters"
"k8s.io/kubernetes/pkg/registry/cachesize"
"k8s.io/kubernetes/pkg/registry/generic"
@ -92,7 +90,7 @@ func Run(s *options.ServerRunOptions) error {
if _, err := genericConfig.ApplySecureServingOptions(s.SecureServing); err != nil {
return fmt.Errorf("failed to configure https: %s", err)
}
if _, err := genericConfig.ApplyAuthenticationOptions(s.Authentication); err != nil {
if err := s.Authentication.Apply(genericConfig); err != nil {
return fmt.Errorf("failed to configure authentication: %s", err)
}
@ -135,7 +133,7 @@ func Run(s *options.ServerRunOptions) error {
storageFactory.SetEtcdLocation(groupResource, servers)
}
apiAuthenticator, securityDefinitions, err := authenticator.New(s.Authentication.ToAuthenticationConfig())
apiAuthenticator, securityDefinitions, err := s.Authentication.ToAuthenticationConfig().New()
if err != nil {
return fmt.Errorf("invalid Authentication Config: %v", err)
}
@ -151,8 +149,8 @@ func Run(s *options.ServerRunOptions) error {
}
sharedInformers := informers.NewSharedInformerFactory(nil, client, 10*time.Minute)
authorizerconfig := s.Authorization.ToAuthorizationConfig(sharedInformers)
apiAuthorizer, err := authorizer.NewAuthorizerFromAuthorizationConfig(authorizerconfig)
authorizationConfig := s.Authorization.ToAuthorizationConfig(sharedInformers)
apiAuthorizer, err := authorizationConfig.New()
if err != nil {
return fmt.Errorf("invalid Authorization Config: %v", err)
}

View File

@ -1,10 +0,0 @@
reviewers:
- smarterclayton
- deads2k
- liggitt
- dims
- spxtr
- errordeveloper
- resouer
- cjcullen
- ericchiang

View File

@ -34,7 +34,6 @@ go_library(
"//pkg/apimachinery/registered:go_default_library",
"//pkg/apis/meta/v1:go_default_library",
"//pkg/apiserver:go_default_library",
"//pkg/apiserver/authenticator:go_default_library",
"//pkg/apiserver/filters:go_default_library",
"//pkg/apiserver/openapi:go_default_library",
"//pkg/apiserver/request:go_default_library",
@ -44,6 +43,7 @@ go_library(
"//pkg/auth/handlers:go_default_library",
"//pkg/auth/user:go_default_library",
"//pkg/client/restclient:go_default_library",
"//pkg/genericapiserver/authenticator:go_default_library",
"//pkg/genericapiserver/authorizer:go_default_library",
"//pkg/genericapiserver/filters:go_default_library",
"//pkg/genericapiserver/mux:go_default_library",

View File

@ -0,0 +1,33 @@
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = [
"delegating.go",
"loopback.go",
"requestheader.go",
],
tags = ["automanaged"],
deps = [
"//pkg/auth/authenticator:go_default_library",
"//pkg/auth/authenticator/bearertoken:go_default_library",
"//pkg/auth/group:go_default_library",
"//pkg/auth/user:go_default_library",
"//pkg/client/clientset_generated/clientset/typed/authentication/v1beta1:go_default_library",
"//pkg/util/cert:go_default_library",
"//plugin/pkg/auth/authenticator/request/anonymous:go_default_library",
"//plugin/pkg/auth/authenticator/request/headerrequest:go_default_library",
"//plugin/pkg/auth/authenticator/request/union:go_default_library",
"//plugin/pkg/auth/authenticator/request/x509:go_default_library",
"//plugin/pkg/auth/authenticator/token/tokenfile:go_default_library",
"//plugin/pkg/auth/authenticator/token/webhook:go_default_library",
"//vendor:github.com/go-openapi/spec",
],
)

View File

@ -0,0 +1,29 @@
/*
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 authenticator
import (
"k8s.io/kubernetes/pkg/auth/authenticator"
"k8s.io/kubernetes/pkg/auth/authenticator/bearertoken"
"k8s.io/kubernetes/pkg/auth/user"
"k8s.io/kubernetes/plugin/pkg/auth/authenticator/token/tokenfile"
)
// newAuthenticatorFromToken returns an authenticator.Request or an error
func NewAuthenticatorFromTokens(tokens map[string]*user.DefaultInfo) authenticator.Request {
return bearertoken.New(tokenfile.New(tokens))
}

View File

@ -0,0 +1,31 @@
/*
Copyright 2014 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 authenticator
type RequestHeaderConfig struct {
// UsernameHeaders are the headers to check (in order, case-insensitively) for an identity. The first header with a value wins.
UsernameHeaders []string
// GroupHeaders are the headers to check (case-insensitively) for a group names. All values will be used.
GroupHeaders []string
// ExtraHeaderPrefixes are the head prefixes to check (case-insentively) for filling in
// the user.Info.Extra. All values of all matching headers will be added.
ExtraHeaderPrefixes []string
// ClientCA points to CA bundle file which is used verify the identity of the front proxy
ClientCA string
// AllowedClientNames is a list of common names that may be presented by the authenticating front proxy. Empty means: accept any.
AllowedClientNames []string
}

View File

@ -17,11 +17,7 @@ go_library(
tags = ["automanaged"],
deps = [
"//pkg/auth/authorizer:go_default_library",
"//pkg/auth/authorizer/abac:go_default_library",
"//pkg/auth/authorizer/union:go_default_library",
"//pkg/client/clientset_generated/clientset/typed/authorization/v1beta1:go_default_library",
"//pkg/controller/informers:go_default_library",
"//plugin/pkg/auth/authorizer/rbac:go_default_library",
"//plugin/pkg/auth/authorizer/webhook:go_default_library",
],
)

View File

@ -41,86 +41,6 @@ func TestNewAlwaysDenyAuthorizer(t *testing.T) {
}
}
// NewAuthorizerFromAuthorizationConfig has multiple return possibilities. This test
// validates that errors are returned only when proper.
func TestNewAuthorizerFromAuthorizationConfig(t *testing.T) {
examplePolicyFile := "../../auth/authorizer/abac/example_policy_file.jsonl"
tests := []struct {
config AuthorizationConfig
wantErr bool
msg string
}{
{
// Unknown modes should return errors
config: AuthorizationConfig{AuthorizationModes: []string{"DoesNotExist"}},
wantErr: true,
msg: "using a fake mode should have returned an error",
},
{
// ModeAlwaysAllow and ModeAlwaysDeny should return without authorizationPolicyFile
// but error if one is given
config: AuthorizationConfig{AuthorizationModes: []string{ModeAlwaysAllow, ModeAlwaysDeny}},
msg: "returned an error for valid config",
},
{
// ModeABAC requires a policy file
config: AuthorizationConfig{AuthorizationModes: []string{ModeAlwaysAllow, ModeAlwaysDeny, ModeABAC}},
wantErr: true,
msg: "specifying ABAC with no policy file should return an error",
},
{
// ModeABAC should not error if a valid policy path is provided
config: AuthorizationConfig{
AuthorizationModes: []string{ModeAlwaysAllow, ModeAlwaysDeny, ModeABAC},
PolicyFile: examplePolicyFile,
},
msg: "errored while using a valid policy file",
},
{
// Authorization Policy file cannot be used without ModeABAC
config: AuthorizationConfig{
AuthorizationModes: []string{ModeAlwaysAllow, ModeAlwaysDeny},
PolicyFile: examplePolicyFile,
},
wantErr: true,
msg: "should have errored when Authorization Policy File is used without ModeABAC",
},
{
// At least one authorizationMode is necessary
config: AuthorizationConfig{PolicyFile: examplePolicyFile},
wantErr: true,
msg: "should have errored when no authorization modes are passed",
},
{
// ModeWebhook requires at minimum a target.
config: AuthorizationConfig{AuthorizationModes: []string{ModeWebhook}},
wantErr: true,
msg: "should have errored when config was empty with ModeWebhook",
},
{
// Cannot provide webhook flags without ModeWebhook
config: AuthorizationConfig{
AuthorizationModes: []string{ModeAlwaysAllow},
WebhookConfigFile: "authz_webhook_config.yml",
},
wantErr: true,
msg: "should have errored when Webhook config file is used without ModeWebhook",
},
}
for _, tt := range tests {
_, err := NewAuthorizerFromAuthorizationConfig(tt.config)
if tt.wantErr && (err == nil) {
t.Errorf("NewAuthorizerFromAuthorizationConfig %s", tt.msg)
} else if !tt.wantErr && (err != nil) {
t.Errorf("NewAuthorizerFromAuthorizationConfig %s: %v", tt.msg, err)
}
}
}
func TestPrivilegedGroupAuthorizer(t *testing.T) {
auth := NewPrivilegedGroups("allow-01", "allow-01")

View File

@ -18,23 +18,8 @@ package authorizer
import (
"errors"
"fmt"
"time"
"k8s.io/kubernetes/pkg/auth/authorizer"
"k8s.io/kubernetes/pkg/auth/authorizer/abac"
"k8s.io/kubernetes/pkg/auth/authorizer/union"
"k8s.io/kubernetes/pkg/controller/informers"
"k8s.io/kubernetes/plugin/pkg/auth/authorizer/rbac"
"k8s.io/kubernetes/plugin/pkg/auth/authorizer/webhook"
)
const (
ModeAlwaysAllow string = "AlwaysAllow"
ModeAlwaysDeny string = "AlwaysDeny"
ModeABAC string = "ABAC"
ModeWebhook string = "Webhook"
ModeRBAC string = "RBAC"
)
// alwaysAllowAuthorizer is an implementation of authorizer.Attributes
@ -100,96 +85,3 @@ func NewPrivilegedGroups(groups ...string) *privilegedGroupAuthorizer {
groups: groups,
}
}
type AuthorizationConfig struct {
AuthorizationModes []string
// Options for ModeABAC
// Path to an ABAC policy file.
PolicyFile string
// Options for ModeWebhook
// Kubeconfig file for Webhook authorization plugin.
WebhookConfigFile string
// TTL for caching of authorized responses from the webhook server.
WebhookCacheAuthorizedTTL time.Duration
// TTL for caching of unauthorized responses from the webhook server.
WebhookCacheUnauthorizedTTL time.Duration
// Options for RBAC
// User which can bootstrap role policies
RBACSuperUser string
InformerFactory informers.SharedInformerFactory
}
// NewAuthorizerFromAuthorizationConfig returns the right sort of union of multiple authorizer.Authorizer objects
// based on the authorizationMode or an error.
func NewAuthorizerFromAuthorizationConfig(config AuthorizationConfig) (authorizer.Authorizer, error) {
if len(config.AuthorizationModes) == 0 {
return nil, errors.New("At least one authorization mode should be passed")
}
var authorizers []authorizer.Authorizer
authorizerMap := make(map[string]bool)
for _, authorizationMode := range config.AuthorizationModes {
if authorizerMap[authorizationMode] {
return nil, fmt.Errorf("Authorization mode %s specified more than once", authorizationMode)
}
// Keep cases in sync with constant list above.
switch authorizationMode {
case ModeAlwaysAllow:
authorizers = append(authorizers, NewAlwaysAllowAuthorizer())
case ModeAlwaysDeny:
authorizers = append(authorizers, NewAlwaysDenyAuthorizer())
case ModeABAC:
if config.PolicyFile == "" {
return nil, errors.New("ABAC's authorization policy file not passed")
}
abacAuthorizer, err := abac.NewFromFile(config.PolicyFile)
if err != nil {
return nil, err
}
authorizers = append(authorizers, abacAuthorizer)
case ModeWebhook:
if config.WebhookConfigFile == "" {
return nil, errors.New("Webhook's configuration file not passed")
}
webhookAuthorizer, err := webhook.New(config.WebhookConfigFile,
config.WebhookCacheAuthorizedTTL,
config.WebhookCacheUnauthorizedTTL)
if err != nil {
return nil, err
}
authorizers = append(authorizers, webhookAuthorizer)
case ModeRBAC:
rbacAuthorizer := rbac.New(
config.InformerFactory.Roles().Lister(),
config.InformerFactory.RoleBindings().Lister(),
config.InformerFactory.ClusterRoles().Lister(),
config.InformerFactory.ClusterRoleBindings().Lister(),
)
authorizers = append(authorizers, rbacAuthorizer)
default:
return nil, fmt.Errorf("Unknown authorization mode %s specified", authorizationMode)
}
authorizerMap[authorizationMode] = true
}
if !authorizerMap[ModeABAC] && config.PolicyFile != "" {
return nil, errors.New("Cannot specify --authorization-policy-file without mode ABAC")
}
if !authorizerMap[ModeWebhook] && config.WebhookConfigFile != "" {
return nil, errors.New("Cannot specify --authorization-webhook-config-file without mode Webhook")
}
if !authorizerMap[ModeRBAC] && config.RBACSuperUser != "" {
return nil, errors.New("Cannot specify --authorization-rbac-super-user without mode RBAC")
}
return union.New(authorizers...), nil
}

View File

@ -39,7 +39,6 @@ import (
"k8s.io/kubernetes/pkg/admission"
"k8s.io/kubernetes/pkg/api"
metav1 "k8s.io/kubernetes/pkg/apis/meta/v1"
apiserverauthenticator "k8s.io/kubernetes/pkg/apiserver/authenticator"
apiserverfilters "k8s.io/kubernetes/pkg/apiserver/filters"
apiserveropenapi "k8s.io/kubernetes/pkg/apiserver/openapi"
apiserverrequest "k8s.io/kubernetes/pkg/apiserver/request"
@ -49,7 +48,8 @@ import (
authhandlers "k8s.io/kubernetes/pkg/auth/handlers"
"k8s.io/kubernetes/pkg/auth/user"
"k8s.io/kubernetes/pkg/client/restclient"
apiserverauthorizer "k8s.io/kubernetes/pkg/genericapiserver/authorizer"
genericauthenticator "k8s.io/kubernetes/pkg/genericapiserver/authenticator"
genericauthorizer "k8s.io/kubernetes/pkg/genericapiserver/authorizer"
genericfilters "k8s.io/kubernetes/pkg/genericapiserver/filters"
"k8s.io/kubernetes/pkg/genericapiserver/mux"
openapicommon "k8s.io/kubernetes/pkg/genericapiserver/openapi/common"
@ -327,30 +327,7 @@ func (c *Config) ApplyInsecureServingOptions(insecureServing *options.ServingOpt
return c
}
func (c *Config) ApplyAuthenticationOptions(o *options.BuiltInAuthenticationOptions) (*Config, error) {
if o == nil || o.PasswordFile == nil {
return c, nil
}
var err error
if o.ClientCert != nil {
c, err = c.applyClientCert(o.ClientCert.ClientCA)
if err != nil {
return nil, fmt.Errorf("unable to load client CA file: %v", err)
}
}
if o.RequestHeader != nil {
c, err = c.applyClientCert(o.RequestHeader.ClientCAFile)
if err != nil {
return nil, fmt.Errorf("unable to load client CA file: %v", err)
}
}
c.SupportsBasicAuth = len(o.PasswordFile.BasicAuthFile) > 0
return c, nil
}
func (c *Config) applyClientCert(clientCAFile string) (*Config, error) {
func (c *Config) ApplyClientCert(clientCAFile string) (*Config, error) {
if c.SecureServingInfo != nil {
if len(clientCAFile) > 0 {
clientCAs, err := certutil.CertsFromFile(clientCAFile)
@ -375,11 +352,11 @@ func (c *Config) ApplyDelegatingAuthenticationOptions(o *options.DelegatingAuthe
}
var err error
c, err = c.applyClientCert(o.ClientCert.ClientCA)
c, err = c.ApplyClientCert(o.ClientCert.ClientCA)
if err != nil {
return nil, fmt.Errorf("unable to load client CA file: %v", err)
}
c, err = c.applyClientCert(o.RequestHeader.ClientCAFile)
c, err = c.ApplyClientCert(o.RequestHeader.ClientCAFile)
if err != nil {
return nil, fmt.Errorf("unable to load client CA file: %v", err)
}
@ -505,10 +482,10 @@ func (c *Config) Complete() completedConfig {
Groups: []string{user.SystemPrivilegedGroup},
}
tokenAuthenticator := apiserverauthenticator.NewAuthenticatorFromTokens(tokens)
tokenAuthenticator := genericauthenticator.NewAuthenticatorFromTokens(tokens)
c.Authenticator = authenticatorunion.New(tokenAuthenticator, c.Authenticator)
tokenAuthorizer := apiserverauthorizer.NewPrivilegedGroups(user.SystemPrivilegedGroup)
tokenAuthorizer := genericauthorizer.NewPrivilegedGroups(user.SystemPrivilegedGroup)
c.Authorizer = authorizerunion.New(tokenAuthorizer, c.Authorizer)
}

View File

@ -23,13 +23,12 @@ go_library(
"//pkg/api:go_default_library",
"//pkg/api/v1:go_default_library",
"//pkg/apimachinery/registered:go_default_library",
"//pkg/apiserver/authenticator:go_default_library",
"//pkg/client/clientset_generated/clientset/typed/authentication/v1beta1:go_default_library",
"//pkg/client/clientset_generated/clientset/typed/authorization/v1beta1:go_default_library",
"//pkg/client/restclient:go_default_library",
"//pkg/client/unversioned/clientcmd:go_default_library",
"//pkg/cloudprovider:go_default_library",
"//pkg/controller/informers:go_default_library",
"//pkg/genericapiserver/authenticator:go_default_library",
"//pkg/genericapiserver/authorizer:go_default_library",
"//pkg/runtime/schema:go_default_library",
"//pkg/storage/storagebackend:go_default_library",

View File

@ -21,279 +21,12 @@ import (
"github.com/spf13/pflag"
"k8s.io/kubernetes/pkg/apiserver/authenticator"
authenticationclient "k8s.io/kubernetes/pkg/client/clientset_generated/clientset/typed/authentication/v1beta1"
"k8s.io/kubernetes/pkg/client/restclient"
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
"k8s.io/kubernetes/pkg/genericapiserver/authenticator"
)
type BuiltInAuthenticationOptions struct {
Anonymous *AnonymousAuthenticationOptions
AnyToken *AnyTokenAuthenticationOptions
ClientCert *ClientCertAuthenticationOptions
Keystone *KeystoneAuthenticationOptions
OIDC *OIDCAuthenticationOptions
PasswordFile *PasswordFileAuthenticationOptions
RequestHeader *RequestHeaderAuthenticationOptions
ServiceAccounts *ServiceAccountAuthenticationOptions
TokenFile *TokenFileAuthenticationOptions
WebHook *WebHookAuthenticationOptions
}
type AnyTokenAuthenticationOptions struct {
Allow bool
}
type AnonymousAuthenticationOptions struct {
Allow bool
}
type KeystoneAuthenticationOptions struct {
URL string
CAFile string
}
type OIDCAuthenticationOptions struct {
CAFile string
ClientID string
IssuerURL string
UsernameClaim string
GroupsClaim string
}
type PasswordFileAuthenticationOptions struct {
BasicAuthFile string
}
type ServiceAccountAuthenticationOptions struct {
KeyFiles []string
Lookup bool
}
type TokenFileAuthenticationOptions struct {
TokenFile string
}
type WebHookAuthenticationOptions struct {
ConfigFile string
CacheTTL time.Duration
}
func NewBuiltInAuthenticationOptions() *BuiltInAuthenticationOptions {
return &BuiltInAuthenticationOptions{}
}
func (s *BuiltInAuthenticationOptions) WithAll() *BuiltInAuthenticationOptions {
return s.
WithAnyonymous().
WithAnyToken().
WithClientCert().
WithKeystone().
WithOIDC().
WithPasswordFile().
WithRequestHeader().
WithServiceAccounts().
WithTokenFile().
WithWebHook()
}
func (s *BuiltInAuthenticationOptions) WithAnyonymous() *BuiltInAuthenticationOptions {
s.Anonymous = &AnonymousAuthenticationOptions{Allow: true}
return s
}
func (s *BuiltInAuthenticationOptions) WithAnyToken() *BuiltInAuthenticationOptions {
s.AnyToken = &AnyTokenAuthenticationOptions{}
return s
}
func (s *BuiltInAuthenticationOptions) WithClientCert() *BuiltInAuthenticationOptions {
s.ClientCert = &ClientCertAuthenticationOptions{}
return s
}
func (s *BuiltInAuthenticationOptions) WithKeystone() *BuiltInAuthenticationOptions {
s.Keystone = &KeystoneAuthenticationOptions{}
return s
}
func (s *BuiltInAuthenticationOptions) WithOIDC() *BuiltInAuthenticationOptions {
s.OIDC = &OIDCAuthenticationOptions{}
return s
}
func (s *BuiltInAuthenticationOptions) WithPasswordFile() *BuiltInAuthenticationOptions {
s.PasswordFile = &PasswordFileAuthenticationOptions{}
return s
}
func (s *BuiltInAuthenticationOptions) WithRequestHeader() *BuiltInAuthenticationOptions {
s.RequestHeader = &RequestHeaderAuthenticationOptions{}
return s
}
func (s *BuiltInAuthenticationOptions) WithServiceAccounts() *BuiltInAuthenticationOptions {
s.ServiceAccounts = &ServiceAccountAuthenticationOptions{}
return s
}
func (s *BuiltInAuthenticationOptions) WithTokenFile() *BuiltInAuthenticationOptions {
s.TokenFile = &TokenFileAuthenticationOptions{}
return s
}
func (s *BuiltInAuthenticationOptions) WithWebHook() *BuiltInAuthenticationOptions {
s.WebHook = &WebHookAuthenticationOptions{
CacheTTL: 2 * time.Minute,
}
return s
}
func (s *BuiltInAuthenticationOptions) Validate() []error {
allErrors := []error{}
return allErrors
}
func (s *BuiltInAuthenticationOptions) AddFlags(fs *pflag.FlagSet) {
if s.Anonymous != nil {
fs.BoolVar(&s.Anonymous.Allow, "anonymous-auth", s.Anonymous.Allow, ""+
"Enables anonymous requests to the secure port of the API server. "+
"Requests that are not rejected by another authentication method are treated as anonymous requests. "+
"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.ClientCert != nil {
s.ClientCert.AddFlags(fs)
}
if s.Keystone != nil {
fs.StringVar(&s.Keystone.URL, "experimental-keystone-url", s.Keystone.URL,
"If passed, activates the keystone authentication plugin.")
fs.StringVar(&s.Keystone.CAFile, "experimental-keystone-ca-file", s.Keystone.CAFile, ""+
"If set, the Keystone server's certificate will be verified by one of the authorities "+
"in the experimental-keystone-ca-file, otherwise the host's root CA set will be used.")
}
if s.OIDC != nil {
fs.StringVar(&s.OIDC.IssuerURL, "oidc-issuer-url", s.OIDC.IssuerURL, ""+
"The URL of the OpenID issuer, only HTTPS scheme will be accepted. "+
"If set, it will be used to verify the OIDC JSON Web Token (JWT).")
fs.StringVar(&s.OIDC.ClientID, "oidc-client-id", s.OIDC.ClientID,
"The client ID for the OpenID Connect client, must be set if oidc-issuer-url is set.")
fs.StringVar(&s.OIDC.CAFile, "oidc-ca-file", s.OIDC.CAFile, ""+
"If set, the OpenID server's certificate will be verified by one of the authorities "+
"in the oidc-ca-file, otherwise the host's root CA set will be used.")
fs.StringVar(&s.OIDC.UsernameClaim, "oidc-username-claim", "sub", ""+
"The OpenID claim to use as the user name. Note that claims other than the default ('sub') "+
"is not guaranteed to be unique and immutable. This flag is experimental, please see "+
"the authentication documentation for further details.")
fs.StringVar(&s.OIDC.GroupsClaim, "oidc-groups-claim", "", ""+
"If provided, the name of a custom OpenID Connect claim for specifying user groups. "+
"The claim value is expected to be a string or array of strings. This flag is experimental, "+
"please see the authentication documentation for further details.")
}
if s.PasswordFile != nil {
fs.StringVar(&s.PasswordFile.BasicAuthFile, "basic-auth-file", s.PasswordFile.BasicAuthFile, ""+
"If set, the file that will be used to admit requests to the secure port of the API server "+
"via http basic authentication.")
}
if s.RequestHeader != nil {
s.RequestHeader.AddFlags(fs)
}
if s.ServiceAccounts != nil {
fs.StringArrayVar(&s.ServiceAccounts.KeyFiles, "service-account-key-file", s.ServiceAccounts.KeyFiles, ""+
"File containing PEM-encoded x509 RSA or ECDSA private or public keys, used to verify "+
"ServiceAccount tokens. If unspecified, --tls-private-key-file is used. "+
"The specified file can contain multiple keys, and the flag can be specified multiple times with different files.")
fs.BoolVar(&s.ServiceAccounts.Lookup, "service-account-lookup", s.ServiceAccounts.Lookup,
"If true, validate ServiceAccount tokens exist in etcd as part of authentication.")
}
if s.TokenFile != nil {
fs.StringVar(&s.TokenFile.TokenFile, "token-auth-file", s.TokenFile.TokenFile, ""+
"If set, the file that will be used to secure the secure port of the API server "+
"via token authentication.")
}
if s.WebHook != nil {
fs.StringVar(&s.WebHook.ConfigFile, "authentication-token-webhook-config-file", s.WebHook.ConfigFile, ""+
"File with webhook configuration for token authentication in kubeconfig format. "+
"The API server will query the remote service to determine authentication for bearer tokens.")
fs.DurationVar(&s.WebHook.CacheTTL, "authentication-token-webhook-cache-ttl", s.WebHook.CacheTTL,
"The duration to cache responses from the webhook token authenticator. Default is 2m.")
}
}
func (s *BuiltInAuthenticationOptions) ToAuthenticationConfig() authenticator.AuthenticatorConfig {
ret := authenticator.AuthenticatorConfig{}
if s.Anonymous != nil {
ret.Anonymous = s.Anonymous.Allow
}
if s.AnyToken != nil {
ret.AnyToken = s.AnyToken.Allow
}
if s.ClientCert != nil {
ret.ClientCAFile = s.ClientCert.ClientCA
}
if s.Keystone != nil {
ret.KeystoneURL = s.Keystone.URL
ret.KeystoneCAFile = s.Keystone.CAFile
}
if s.OIDC != nil {
ret.OIDCCAFile = s.OIDC.CAFile
ret.OIDCClientID = s.OIDC.ClientID
ret.OIDCGroupsClaim = s.OIDC.GroupsClaim
ret.OIDCIssuerURL = s.OIDC.IssuerURL
ret.OIDCUsernameClaim = s.OIDC.UsernameClaim
}
if s.PasswordFile != nil {
ret.BasicAuthFile = s.PasswordFile.BasicAuthFile
}
if s.RequestHeader != nil {
ret.RequestHeaderConfig = s.RequestHeader.ToAuthenticationRequestHeaderConfig()
}
if s.ServiceAccounts != nil {
ret.ServiceAccountKeyFiles = s.ServiceAccounts.KeyFiles
ret.ServiceAccountLookup = s.ServiceAccounts.Lookup
}
if s.TokenFile != nil {
ret.TokenAuthFile = s.TokenFile.TokenFile
}
if s.WebHook != nil {
ret.WebhookTokenAuthnConfigFile = s.WebHook.ConfigFile
ret.WebhookTokenAuthnCacheTTL = s.WebHook.CacheTTL
}
return ret
}
type RequestHeaderAuthenticationOptions struct {
UsernameHeaders []string
GroupHeaders []string

View File

@ -17,7 +17,6 @@ limitations under the License.
package options
import (
"strings"
"time"
"github.com/spf13/pflag"
@ -25,76 +24,9 @@ import (
authorizationclient "k8s.io/kubernetes/pkg/client/clientset_generated/clientset/typed/authorization/v1beta1"
"k8s.io/kubernetes/pkg/client/restclient"
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
"k8s.io/kubernetes/pkg/controller/informers"
"k8s.io/kubernetes/pkg/genericapiserver/authorizer"
)
var AuthorizationModeChoices = []string{authorizer.ModeAlwaysAllow, authorizer.ModeAlwaysDeny, authorizer.ModeABAC, authorizer.ModeWebhook, authorizer.ModeRBAC}
type BuiltInAuthorizationOptions struct {
Mode string
PolicyFile string
WebhookConfigFile string
WebhookCacheAuthorizedTTL time.Duration
WebhookCacheUnauthorizedTTL time.Duration
}
func NewBuiltInAuthorizationOptions() *BuiltInAuthorizationOptions {
return &BuiltInAuthorizationOptions{
Mode: authorizer.ModeAlwaysAllow,
WebhookCacheAuthorizedTTL: 5 * time.Minute,
WebhookCacheUnauthorizedTTL: 30 * time.Second,
}
}
func (s *BuiltInAuthorizationOptions) Validate() []error {
allErrors := []error{}
return allErrors
}
func (s *BuiltInAuthorizationOptions) AddFlags(fs *pflag.FlagSet) {
fs.StringVar(&s.Mode, "authorization-mode", s.Mode, ""+
"Ordered list of plug-ins to do authorization on secure port. Comma-delimited list of: "+
strings.Join(AuthorizationModeChoices, ",")+".")
fs.StringVar(&s.PolicyFile, "authorization-policy-file", s.PolicyFile, ""+
"File with authorization policy in csv format, used with --authorization-mode=ABAC, on the secure port.")
fs.StringVar(&s.WebhookConfigFile, "authorization-webhook-config-file", s.WebhookConfigFile, ""+
"File with webhook configuration in kubeconfig format, used with --authorization-mode=Webhook. "+
"The API server will query the remote service to determine access on the API server's secure port.")
fs.DurationVar(&s.WebhookCacheAuthorizedTTL, "authorization-webhook-cache-authorized-ttl",
s.WebhookCacheAuthorizedTTL,
"The duration to cache 'authorized' responses from the webhook authorizer. Default is 5m.")
fs.DurationVar(&s.WebhookCacheUnauthorizedTTL,
"authorization-webhook-cache-unauthorized-ttl", s.WebhookCacheUnauthorizedTTL,
"The duration to cache 'unauthorized' responses from the webhook authorizer. Default is 30s.")
fs.String("authorization-rbac-super-user", "", ""+
"If specified, a username which avoids RBAC authorization checks and role binding "+
"privilege escalation checks, to be used with --authorization-mode=RBAC.")
fs.MarkDeprecated("authorization-rbac-super-user", "Removed during alpha to beta. The 'system:masters' group has privileged access.")
}
func (s *BuiltInAuthorizationOptions) ToAuthorizationConfig(informerFactory informers.SharedInformerFactory) authorizer.AuthorizationConfig {
modes := []string{}
if len(s.Mode) > 0 {
modes = strings.Split(s.Mode, ",")
}
return authorizer.AuthorizationConfig{
AuthorizationModes: modes,
PolicyFile: s.PolicyFile,
WebhookConfigFile: s.WebhookConfigFile,
WebhookCacheAuthorizedTTL: s.WebhookCacheAuthorizedTTL,
WebhookCacheUnauthorizedTTL: s.WebhookCacheUnauthorizedTTL,
InformerFactory: informerFactory,
}
}
// DelegatingAuthorizationOptions provides an easy way for composing API servers to delegate their authorization to
// the root kube API server
type DelegatingAuthorizationOptions struct {

14
pkg/kubeapiserver/BUILD Normal file
View File

@ -0,0 +1,14 @@
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = ["doc.go"],
tags = ["automanaged"],
)

View File

@ -9,17 +9,14 @@ load(
go_library(
name = "go_default_library",
srcs = [
"builtin.go",
"delegating.go",
],
srcs = ["config.go"],
tags = ["automanaged"],
deps = [
"//pkg/auth/authenticator:go_default_library",
"//pkg/auth/authenticator/bearertoken:go_default_library",
"//pkg/auth/group:go_default_library",
"//pkg/auth/user:go_default_library",
"//pkg/client/clientset_generated/clientset/typed/authentication/v1beta1:go_default_library",
"//pkg/genericapiserver/authenticator:go_default_library",
"//pkg/serviceaccount:go_default_library",
"//pkg/util/cert:go_default_library",
"//plugin/pkg/auth/authenticator/password/keystone:go_default_library",

View File

@ -25,6 +25,7 @@ import (
"k8s.io/kubernetes/pkg/auth/authenticator/bearertoken"
"k8s.io/kubernetes/pkg/auth/group"
"k8s.io/kubernetes/pkg/auth/user"
genericauthenticator "k8s.io/kubernetes/pkg/genericapiserver/authenticator"
"k8s.io/kubernetes/pkg/serviceaccount"
certutil "k8s.io/kubernetes/pkg/util/cert"
"k8s.io/kubernetes/plugin/pkg/auth/authenticator/password/keystone"
@ -40,20 +41,6 @@ import (
"k8s.io/kubernetes/plugin/pkg/auth/authenticator/token/webhook"
)
type RequestHeaderConfig struct {
// UsernameHeaders are the headers to check (in order, case-insensitively) for an identity. The first header with a value wins.
UsernameHeaders []string
// GroupHeaders are the headers to check (case-insensitively) for a group names. All values will be used.
GroupHeaders []string
// ExtraHeaderPrefixes are the head prefixes to check (case-insentively) for filling in
// the user.Info.Extra. All values of all matching headers will be added.
ExtraHeaderPrefixes []string
// ClientCA points to CA bundle file which is used verify the identity of the front proxy
ClientCA string
// AllowedClientNames is a list of common names that may be presented by the authenticating front proxy. Empty means: accept any.
AllowedClientNames []string
}
type AuthenticatorConfig struct {
Anonymous bool
AnyToken bool
@ -72,7 +59,7 @@ type AuthenticatorConfig struct {
WebhookTokenAuthnConfigFile string
WebhookTokenAuthnCacheTTL time.Duration
RequestHeaderConfig *RequestHeaderConfig
RequestHeaderConfig *genericauthenticator.RequestHeaderConfig
// TODO, this is the only non-serializable part of the entire config. Factor it out into a clientconfig
ServiceAccountTokenGetter serviceaccount.ServiceAccountTokenGetter
@ -80,7 +67,7 @@ type AuthenticatorConfig struct {
// New returns an authenticator.Request or an error that supports the standard
// Kubernetes authentication mechanisms.
func New(config AuthenticatorConfig) (authenticator.Request, *spec.SecurityDefinitions, error) {
func (config AuthenticatorConfig) New() (authenticator.Request, *spec.SecurityDefinitions, error) {
var authenticators []authenticator.Request
securityDefinitions := spec.SecurityDefinitions{}
hasBasicAuth := false
@ -243,11 +230,6 @@ func newAuthenticatorFromTokenFile(tokenAuthFile string) (authenticator.Request,
return bearertoken.New(tokenAuthenticator), nil
}
// newAuthenticatorFromToken returns an authenticator.Request or an error
func NewAuthenticatorFromTokens(tokens map[string]*user.DefaultInfo) authenticator.Request {
return bearertoken.New(tokenfile.New(tokens))
}
// newAuthenticatorFromOIDCIssuerURL returns an authenticator.Request or an error.
func newAuthenticatorFromOIDCIssuerURL(issuerURL, clientID, caFile, usernameClaim, groupsClaim string) (authenticator.Request, error) {
tokenAuthenticator, err := oidc.New(oidc.OIDCOptions{

View File

@ -0,0 +1,35 @@
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 = ["config_test.go"],
data = [
"//pkg/auth/authorizer/abac:example_policy",
],
library = "go_default_library",
tags = ["automanaged"],
deps = [],
)
go_library(
name = "go_default_library",
srcs = ["config.go"],
tags = ["automanaged"],
deps = [
"//pkg/auth/authorizer:go_default_library",
"//pkg/auth/authorizer/abac:go_default_library",
"//pkg/auth/authorizer/union:go_default_library",
"//pkg/controller/informers:go_default_library",
"//pkg/genericapiserver/authorizer:go_default_library",
"//plugin/pkg/auth/authorizer/rbac:go_default_library",
"//plugin/pkg/auth/authorizer/webhook:go_default_library",
],
)

View File

@ -0,0 +1,131 @@
/*
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 authorizer
import (
"errors"
"fmt"
"time"
"k8s.io/kubernetes/pkg/auth/authorizer"
"k8s.io/kubernetes/pkg/auth/authorizer/abac"
"k8s.io/kubernetes/pkg/auth/authorizer/union"
"k8s.io/kubernetes/pkg/controller/informers"
genericauthorizer "k8s.io/kubernetes/pkg/genericapiserver/authorizer"
"k8s.io/kubernetes/plugin/pkg/auth/authorizer/rbac"
"k8s.io/kubernetes/plugin/pkg/auth/authorizer/webhook"
)
const (
ModeAlwaysAllow string = "AlwaysAllow"
ModeAlwaysDeny string = "AlwaysDeny"
ModeABAC string = "ABAC"
ModeWebhook string = "Webhook"
ModeRBAC string = "RBAC"
)
type AuthorizationConfig struct {
AuthorizationModes []string
// Options for ModeABAC
// Path to an ABAC policy file.
PolicyFile string
// Options for ModeWebhook
// Kubeconfig file for Webhook authorization plugin.
WebhookConfigFile string
// TTL for caching of authorized responses from the webhook server.
WebhookCacheAuthorizedTTL time.Duration
// TTL for caching of unauthorized responses from the webhook server.
WebhookCacheUnauthorizedTTL time.Duration
// Options for RBAC
// User which can bootstrap role policies
RBACSuperUser string
InformerFactory informers.SharedInformerFactory
}
// New returns the right sort of union of multiple authorizer.Authorizer objects
// based on the authorizationMode or an error.
func (config AuthorizationConfig) New() (authorizer.Authorizer, error) {
if len(config.AuthorizationModes) == 0 {
return nil, errors.New("At least one authorization mode should be passed")
}
var authorizers []authorizer.Authorizer
authorizerMap := make(map[string]bool)
for _, authorizationMode := range config.AuthorizationModes {
if authorizerMap[authorizationMode] {
return nil, fmt.Errorf("Authorization mode %s specified more than once", authorizationMode)
}
// Keep cases in sync with constant list above.
switch authorizationMode {
case ModeAlwaysAllow:
authorizers = append(authorizers, genericauthorizer.NewAlwaysAllowAuthorizer())
case ModeAlwaysDeny:
authorizers = append(authorizers, genericauthorizer.NewAlwaysDenyAuthorizer())
case ModeABAC:
if config.PolicyFile == "" {
return nil, errors.New("ABAC's authorization policy file not passed")
}
abacAuthorizer, err := abac.NewFromFile(config.PolicyFile)
if err != nil {
return nil, err
}
authorizers = append(authorizers, abacAuthorizer)
case ModeWebhook:
if config.WebhookConfigFile == "" {
return nil, errors.New("Webhook's configuration file not passed")
}
webhookAuthorizer, err := webhook.New(config.WebhookConfigFile,
config.WebhookCacheAuthorizedTTL,
config.WebhookCacheUnauthorizedTTL)
if err != nil {
return nil, err
}
authorizers = append(authorizers, webhookAuthorizer)
case ModeRBAC:
rbacAuthorizer := rbac.New(
config.InformerFactory.Roles().Lister(),
config.InformerFactory.RoleBindings().Lister(),
config.InformerFactory.ClusterRoles().Lister(),
config.InformerFactory.ClusterRoleBindings().Lister(),
)
authorizers = append(authorizers, rbacAuthorizer)
default:
return nil, fmt.Errorf("Unknown authorization mode %s specified", authorizationMode)
}
authorizerMap[authorizationMode] = true
}
if !authorizerMap[ModeABAC] && config.PolicyFile != "" {
return nil, errors.New("Cannot specify --authorization-policy-file without mode ABAC")
}
if !authorizerMap[ModeWebhook] && config.WebhookConfigFile != "" {
return nil, errors.New("Cannot specify --authorization-webhook-config-file without mode Webhook")
}
if !authorizerMap[ModeRBAC] && config.RBACSuperUser != "" {
return nil, errors.New("Cannot specify --authorization-rbac-super-user without mode RBAC")
}
return union.New(authorizers...), nil
}

View File

@ -0,0 +1,100 @@
/*
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 authorizer
import (
"testing"
)
// New has multiple return possibilities. This test
// validates that errors are returned only when proper.
func TestNew(t *testing.T) {
examplePolicyFile := "../../auth/authorizer/abac/example_policy_file.jsonl"
tests := []struct {
config AuthorizationConfig
wantErr bool
msg string
}{
{
// Unknown modes should return errors
config: AuthorizationConfig{AuthorizationModes: []string{"DoesNotExist"}},
wantErr: true,
msg: "using a fake mode should have returned an error",
},
{
// ModeAlwaysAllow and ModeAlwaysDeny should return without authorizationPolicyFile
// but error if one is given
config: AuthorizationConfig{AuthorizationModes: []string{ModeAlwaysAllow, ModeAlwaysDeny}},
msg: "returned an error for valid config",
},
{
// ModeABAC requires a policy file
config: AuthorizationConfig{AuthorizationModes: []string{ModeAlwaysAllow, ModeAlwaysDeny, ModeABAC}},
wantErr: true,
msg: "specifying ABAC with no policy file should return an error",
},
{
// ModeABAC should not error if a valid policy path is provided
config: AuthorizationConfig{
AuthorizationModes: []string{ModeAlwaysAllow, ModeAlwaysDeny, ModeABAC},
PolicyFile: examplePolicyFile,
},
msg: "errored while using a valid policy file",
},
{
// Authorization Policy file cannot be used without ModeABAC
config: AuthorizationConfig{
AuthorizationModes: []string{ModeAlwaysAllow, ModeAlwaysDeny},
PolicyFile: examplePolicyFile,
},
wantErr: true,
msg: "should have errored when Authorization Policy File is used without ModeABAC",
},
{
// At least one authorizationMode is necessary
config: AuthorizationConfig{PolicyFile: examplePolicyFile},
wantErr: true,
msg: "should have errored when no authorization modes are passed",
},
{
// ModeWebhook requires at minimum a target.
config: AuthorizationConfig{AuthorizationModes: []string{ModeWebhook}},
wantErr: true,
msg: "should have errored when config was empty with ModeWebhook",
},
{
// Cannot provide webhook flags without ModeWebhook
config: AuthorizationConfig{
AuthorizationModes: []string{ModeAlwaysAllow},
WebhookConfigFile: "authz_webhook_config.yml",
},
wantErr: true,
msg: "should have errored when Webhook config file is used without ModeWebhook",
},
}
for _, tt := range tests {
_, err := tt.config.New()
if tt.wantErr && (err == nil) {
t.Errorf("New %s", tt.msg)
} else if !tt.wantErr && (err != nil) {
t.Errorf("New %s: %v", tt.msg, err)
}
}
}

21
pkg/kubeapiserver/doc.go Normal file
View File

@ -0,0 +1,21 @@
/*
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.
*/
// The kubapiserver package holds code that is common to both the kube-apiserver
// and the federation-apiserver, but isn't part of a generic API server.
// For instance, the non-delegated authorization options are used by those two
// servers, but no generic API server is likely to use them.
package kubeapiserver

View File

@ -0,0 +1,25 @@
package(default_visibility = ["//visibility:public"])
licenses(["notice"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_library",
)
go_library(
name = "go_default_library",
srcs = [
"authentication.go",
"authorization.go",
],
tags = ["automanaged"],
deps = [
"//pkg/controller/informers:go_default_library",
"//pkg/genericapiserver:go_default_library",
"//pkg/genericapiserver/options:go_default_library",
"//pkg/kubeapiserver/authenticator:go_default_library",
"//pkg/kubeapiserver/authorizer:go_default_library",
"//vendor:github.com/spf13/pflag",
],
)

View File

@ -0,0 +1,318 @@
/*
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 options
import (
"fmt"
"time"
"github.com/spf13/pflag"
"k8s.io/kubernetes/pkg/genericapiserver"
genericoptions "k8s.io/kubernetes/pkg/genericapiserver/options"
"k8s.io/kubernetes/pkg/kubeapiserver/authenticator"
)
type BuiltInAuthenticationOptions struct {
Anonymous *AnonymousAuthenticationOptions
AnyToken *AnyTokenAuthenticationOptions
ClientCert *genericoptions.ClientCertAuthenticationOptions
Keystone *KeystoneAuthenticationOptions
OIDC *OIDCAuthenticationOptions
PasswordFile *PasswordFileAuthenticationOptions
RequestHeader *genericoptions.RequestHeaderAuthenticationOptions
ServiceAccounts *ServiceAccountAuthenticationOptions
TokenFile *TokenFileAuthenticationOptions
WebHook *WebHookAuthenticationOptions
}
type AnyTokenAuthenticationOptions struct {
Allow bool
}
type AnonymousAuthenticationOptions struct {
Allow bool
}
type KeystoneAuthenticationOptions struct {
URL string
CAFile string
}
type OIDCAuthenticationOptions struct {
CAFile string
ClientID string
IssuerURL string
UsernameClaim string
GroupsClaim string
}
type PasswordFileAuthenticationOptions struct {
BasicAuthFile string
}
type ServiceAccountAuthenticationOptions struct {
KeyFiles []string
Lookup bool
}
type TokenFileAuthenticationOptions struct {
TokenFile string
}
type WebHookAuthenticationOptions struct {
ConfigFile string
CacheTTL time.Duration
}
func NewBuiltInAuthenticationOptions() *BuiltInAuthenticationOptions {
return &BuiltInAuthenticationOptions{}
}
func (s *BuiltInAuthenticationOptions) WithAll() *BuiltInAuthenticationOptions {
return s.
WithAnyonymous().
WithAnyToken().
WithClientCert().
WithKeystone().
WithOIDC().
WithPasswordFile().
WithRequestHeader().
WithServiceAccounts().
WithTokenFile().
WithWebHook()
}
func (s *BuiltInAuthenticationOptions) WithAnyonymous() *BuiltInAuthenticationOptions {
s.Anonymous = &AnonymousAuthenticationOptions{Allow: true}
return s
}
func (s *BuiltInAuthenticationOptions) WithAnyToken() *BuiltInAuthenticationOptions {
s.AnyToken = &AnyTokenAuthenticationOptions{}
return s
}
func (s *BuiltInAuthenticationOptions) WithClientCert() *BuiltInAuthenticationOptions {
s.ClientCert = &genericoptions.ClientCertAuthenticationOptions{}
return s
}
func (s *BuiltInAuthenticationOptions) WithKeystone() *BuiltInAuthenticationOptions {
s.Keystone = &KeystoneAuthenticationOptions{}
return s
}
func (s *BuiltInAuthenticationOptions) WithOIDC() *BuiltInAuthenticationOptions {
s.OIDC = &OIDCAuthenticationOptions{}
return s
}
func (s *BuiltInAuthenticationOptions) WithPasswordFile() *BuiltInAuthenticationOptions {
s.PasswordFile = &PasswordFileAuthenticationOptions{}
return s
}
func (s *BuiltInAuthenticationOptions) WithRequestHeader() *BuiltInAuthenticationOptions {
s.RequestHeader = &genericoptions.RequestHeaderAuthenticationOptions{}
return s
}
func (s *BuiltInAuthenticationOptions) WithServiceAccounts() *BuiltInAuthenticationOptions {
s.ServiceAccounts = &ServiceAccountAuthenticationOptions{}
return s
}
func (s *BuiltInAuthenticationOptions) WithTokenFile() *BuiltInAuthenticationOptions {
s.TokenFile = &TokenFileAuthenticationOptions{}
return s
}
func (s *BuiltInAuthenticationOptions) WithWebHook() *BuiltInAuthenticationOptions {
s.WebHook = &WebHookAuthenticationOptions{
CacheTTL: 2 * time.Minute,
}
return s
}
func (s *BuiltInAuthenticationOptions) Validate() []error {
allErrors := []error{}
return allErrors
}
func (s *BuiltInAuthenticationOptions) AddFlags(fs *pflag.FlagSet) {
if s.Anonymous != nil {
fs.BoolVar(&s.Anonymous.Allow, "anonymous-auth", s.Anonymous.Allow, ""+
"Enables anonymous requests to the secure port of the API server. "+
"Requests that are not rejected by another authentication method are treated as anonymous requests. "+
"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.ClientCert != nil {
s.ClientCert.AddFlags(fs)
}
if s.Keystone != nil {
fs.StringVar(&s.Keystone.URL, "experimental-keystone-url", s.Keystone.URL,
"If passed, activates the keystone authentication plugin.")
fs.StringVar(&s.Keystone.CAFile, "experimental-keystone-ca-file", s.Keystone.CAFile, ""+
"If set, the Keystone server's certificate will be verified by one of the authorities "+
"in the experimental-keystone-ca-file, otherwise the host's root CA set will be used.")
}
if s.OIDC != nil {
fs.StringVar(&s.OIDC.IssuerURL, "oidc-issuer-url", s.OIDC.IssuerURL, ""+
"The URL of the OpenID issuer, only HTTPS scheme will be accepted. "+
"If set, it will be used to verify the OIDC JSON Web Token (JWT).")
fs.StringVar(&s.OIDC.ClientID, "oidc-client-id", s.OIDC.ClientID,
"The client ID for the OpenID Connect client, must be set if oidc-issuer-url is set.")
fs.StringVar(&s.OIDC.CAFile, "oidc-ca-file", s.OIDC.CAFile, ""+
"If set, the OpenID server's certificate will be verified by one of the authorities "+
"in the oidc-ca-file, otherwise the host's root CA set will be used.")
fs.StringVar(&s.OIDC.UsernameClaim, "oidc-username-claim", "sub", ""+
"The OpenID claim to use as the user name. Note that claims other than the default ('sub') "+
"is not guaranteed to be unique and immutable. This flag is experimental, please see "+
"the authentication documentation for further details.")
fs.StringVar(&s.OIDC.GroupsClaim, "oidc-groups-claim", "", ""+
"If provided, the name of a custom OpenID Connect claim for specifying user groups. "+
"The claim value is expected to be a string or array of strings. This flag is experimental, "+
"please see the authentication documentation for further details.")
}
if s.PasswordFile != nil {
fs.StringVar(&s.PasswordFile.BasicAuthFile, "basic-auth-file", s.PasswordFile.BasicAuthFile, ""+
"If set, the file that will be used to admit requests to the secure port of the API server "+
"via http basic authentication.")
}
if s.RequestHeader != nil {
s.RequestHeader.AddFlags(fs)
}
if s.ServiceAccounts != nil {
fs.StringArrayVar(&s.ServiceAccounts.KeyFiles, "service-account-key-file", s.ServiceAccounts.KeyFiles, ""+
"File containing PEM-encoded x509 RSA or ECDSA private or public keys, used to verify "+
"ServiceAccount tokens. If unspecified, --tls-private-key-file is used. "+
"The specified file can contain multiple keys, and the flag can be specified multiple times with different files.")
fs.BoolVar(&s.ServiceAccounts.Lookup, "service-account-lookup", s.ServiceAccounts.Lookup,
"If true, validate ServiceAccount tokens exist in etcd as part of authentication.")
}
if s.TokenFile != nil {
fs.StringVar(&s.TokenFile.TokenFile, "token-auth-file", s.TokenFile.TokenFile, ""+
"If set, the file that will be used to secure the secure port of the API server "+
"via token authentication.")
}
if s.WebHook != nil {
fs.StringVar(&s.WebHook.ConfigFile, "authentication-token-webhook-config-file", s.WebHook.ConfigFile, ""+
"File with webhook configuration for token authentication in kubeconfig format. "+
"The API server will query the remote service to determine authentication for bearer tokens.")
fs.DurationVar(&s.WebHook.CacheTTL, "authentication-token-webhook-cache-ttl", s.WebHook.CacheTTL,
"The duration to cache responses from the webhook token authenticator. Default is 2m.")
}
}
func (s *BuiltInAuthenticationOptions) ToAuthenticationConfig() authenticator.AuthenticatorConfig {
ret := authenticator.AuthenticatorConfig{}
if s.Anonymous != nil {
ret.Anonymous = s.Anonymous.Allow
}
if s.AnyToken != nil {
ret.AnyToken = s.AnyToken.Allow
}
if s.ClientCert != nil {
ret.ClientCAFile = s.ClientCert.ClientCA
}
if s.Keystone != nil {
ret.KeystoneURL = s.Keystone.URL
ret.KeystoneCAFile = s.Keystone.CAFile
}
if s.OIDC != nil {
ret.OIDCCAFile = s.OIDC.CAFile
ret.OIDCClientID = s.OIDC.ClientID
ret.OIDCGroupsClaim = s.OIDC.GroupsClaim
ret.OIDCIssuerURL = s.OIDC.IssuerURL
ret.OIDCUsernameClaim = s.OIDC.UsernameClaim
}
if s.PasswordFile != nil {
ret.BasicAuthFile = s.PasswordFile.BasicAuthFile
}
if s.RequestHeader != nil {
ret.RequestHeaderConfig = s.RequestHeader.ToAuthenticationRequestHeaderConfig()
}
if s.ServiceAccounts != nil {
ret.ServiceAccountKeyFiles = s.ServiceAccounts.KeyFiles
ret.ServiceAccountLookup = s.ServiceAccounts.Lookup
}
if s.TokenFile != nil {
ret.TokenAuthFile = s.TokenFile.TokenFile
}
if s.WebHook != nil {
ret.WebhookTokenAuthnConfigFile = s.WebHook.ConfigFile
ret.WebhookTokenAuthnCacheTTL = s.WebHook.CacheTTL
}
return ret
}
func (o *BuiltInAuthenticationOptions) Apply(c *genericapiserver.Config) error {
if o == nil || o.PasswordFile == nil {
return nil
}
var err error
if o.ClientCert != nil {
c, err = c.ApplyClientCert(o.ClientCert.ClientCA)
if err != nil {
return fmt.Errorf("unable to load client CA file: %v", err)
}
}
if o.RequestHeader != nil {
c, err = c.ApplyClientCert(o.RequestHeader.ClientCAFile)
if err != nil {
return fmt.Errorf("unable to load client CA file: %v", err)
}
}
c.SupportsBasicAuth = len(o.PasswordFile.BasicAuthFile) > 0
return nil
}

View File

@ -0,0 +1,93 @@
/*
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 options
import (
"strings"
"time"
"github.com/spf13/pflag"
"k8s.io/kubernetes/pkg/controller/informers"
"k8s.io/kubernetes/pkg/kubeapiserver/authorizer"
)
var AuthorizationModeChoices = []string{authorizer.ModeAlwaysAllow, authorizer.ModeAlwaysDeny, authorizer.ModeABAC, authorizer.ModeWebhook, authorizer.ModeRBAC}
type BuiltInAuthorizationOptions struct {
Mode string
PolicyFile string
WebhookConfigFile string
WebhookCacheAuthorizedTTL time.Duration
WebhookCacheUnauthorizedTTL time.Duration
}
func NewBuiltInAuthorizationOptions() *BuiltInAuthorizationOptions {
return &BuiltInAuthorizationOptions{
Mode: authorizer.ModeAlwaysAllow,
WebhookCacheAuthorizedTTL: 5 * time.Minute,
WebhookCacheUnauthorizedTTL: 30 * time.Second,
}
}
func (s *BuiltInAuthorizationOptions) Validate() []error {
allErrors := []error{}
return allErrors
}
func (s *BuiltInAuthorizationOptions) AddFlags(fs *pflag.FlagSet) {
fs.StringVar(&s.Mode, "authorization-mode", s.Mode, ""+
"Ordered list of plug-ins to do authorization on secure port. Comma-delimited list of: "+
strings.Join(AuthorizationModeChoices, ",")+".")
fs.StringVar(&s.PolicyFile, "authorization-policy-file", s.PolicyFile, ""+
"File with authorization policy in csv format, used with --authorization-mode=ABAC, on the secure port.")
fs.StringVar(&s.WebhookConfigFile, "authorization-webhook-config-file", s.WebhookConfigFile, ""+
"File with webhook configuration in kubeconfig format, used with --authorization-mode=Webhook. "+
"The API server will query the remote service to determine access on the API server's secure port.")
fs.DurationVar(&s.WebhookCacheAuthorizedTTL, "authorization-webhook-cache-authorized-ttl",
s.WebhookCacheAuthorizedTTL,
"The duration to cache 'authorized' responses from the webhook authorizer. Default is 5m.")
fs.DurationVar(&s.WebhookCacheUnauthorizedTTL,
"authorization-webhook-cache-unauthorized-ttl", s.WebhookCacheUnauthorizedTTL,
"The duration to cache 'unauthorized' responses from the webhook authorizer. Default is 30s.")
fs.String("authorization-rbac-super-user", "", ""+
"If specified, a username which avoids RBAC authorization checks and role binding "+
"privilege escalation checks, to be used with --authorization-mode=RBAC.")
fs.MarkDeprecated("authorization-rbac-super-user", "Removed during alpha to beta. The 'system:masters' group has privileged access.")
}
func (s *BuiltInAuthorizationOptions) ToAuthorizationConfig(informerFactory informers.SharedInformerFactory) authorizer.AuthorizationConfig {
modes := []string{}
if len(s.Mode) > 0 {
modes = strings.Split(s.Mode, ",")
}
return authorizer.AuthorizationConfig{
AuthorizationModes: modes,
PolicyFile: s.PolicyFile,
WebhookConfigFile: s.WebhookConfigFile,
WebhookCacheAuthorizedTTL: s.WebhookCacheAuthorizedTTL,
WebhookCacheUnauthorizedTTL: s.WebhookCacheUnauthorizedTTL,
InformerFactory: informerFactory,
}
}

View File

@ -30,7 +30,6 @@ go_library(
"//pkg/apis/policy/v1alpha1:go_default_library",
"//pkg/apis/rbac/v1alpha1:go_default_library",
"//pkg/apis/storage/v1beta1:go_default_library",
"//pkg/apiserver/authenticator:go_default_library",
"//pkg/auth/authenticator:go_default_library",
"//pkg/auth/authorizer:go_default_library",
"//pkg/auth/authorizer/union:go_default_library",
@ -44,6 +43,7 @@ go_library(
"//pkg/controller/replication:go_default_library",
"//pkg/generated/openapi:go_default_library",
"//pkg/genericapiserver:go_default_library",
"//pkg/genericapiserver/authenticator:go_default_library",
"//pkg/genericapiserver/authorizer:go_default_library",
"//pkg/kubectl:go_default_library",
"//pkg/kubelet/client:go_default_library",

View File

@ -40,7 +40,6 @@ import (
policy "k8s.io/kubernetes/pkg/apis/policy/v1alpha1"
rbac "k8s.io/kubernetes/pkg/apis/rbac/v1alpha1"
storage "k8s.io/kubernetes/pkg/apis/storage/v1beta1"
"k8s.io/kubernetes/pkg/apiserver/authenticator"
authauthenticator "k8s.io/kubernetes/pkg/auth/authenticator"
authauthorizer "k8s.io/kubernetes/pkg/auth/authorizer"
authorizerunion "k8s.io/kubernetes/pkg/auth/authorizer/union"
@ -54,6 +53,7 @@ import (
replicationcontroller "k8s.io/kubernetes/pkg/controller/replication"
"k8s.io/kubernetes/pkg/generated/openapi"
"k8s.io/kubernetes/pkg/genericapiserver"
"k8s.io/kubernetes/pkg/genericapiserver/authenticator"
"k8s.io/kubernetes/pkg/genericapiserver/authorizer"
"k8s.io/kubernetes/pkg/kubectl"
kubeletclient "k8s.io/kubernetes/pkg/kubelet/client"