mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-30 23:15:14 +00:00
use AuthorizationConfiguration in kube-apiserver for storing authorizer config
Signed-off-by: Nabarun Pal <pal.nabarun95@gmail.com>
This commit is contained in:
parent
52c582ca77
commit
108d195595
@ -174,7 +174,10 @@ func BuildGenericConfig(
|
||||
|
||||
// BuildAuthorizer constructs the authorizer
|
||||
func BuildAuthorizer(s controlplaneapiserver.CompletedOptions, EgressSelector *egressselector.EgressSelector, versionedInformers clientgoinformers.SharedInformerFactory) (authorizer.Authorizer, authorizer.RuleResolver, error) {
|
||||
authorizationConfig := s.Authorization.ToAuthorizationConfig(versionedInformers)
|
||||
authorizationConfig, err := s.Authorization.ToAuthorizationConfig(versionedInformers)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if EgressSelector != nil {
|
||||
egressDialer, err := EgressSelector.Lookup(egressselector.ControlPlane.AsNetworkContext())
|
||||
|
@ -19,10 +19,9 @@ package authorizer
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
utilnet "k8s.io/apimachinery/pkg/util/net"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
authzconfig "k8s.io/apiserver/pkg/apis/apiserver"
|
||||
"k8s.io/apiserver/pkg/authentication/user"
|
||||
"k8s.io/apiserver/pkg/authorization/authorizer"
|
||||
"k8s.io/apiserver/pkg/authorization/authorizerfactory"
|
||||
@ -40,8 +39,6 @@ import (
|
||||
|
||||
// Config contains the data on how to authorize a request to the Kube API Server
|
||||
type Config struct {
|
||||
AuthorizationModes []string
|
||||
|
||||
// Options for ModeABAC
|
||||
|
||||
// Path to an ABAC policy file.
|
||||
@ -49,14 +46,6 @@ type Config struct {
|
||||
|
||||
// Options for ModeWebhook
|
||||
|
||||
// Kubeconfig file for Webhook authorization plugin.
|
||||
WebhookConfigFile string
|
||||
// API version of subject access reviews to send to the webhook (e.g. "v1", "v1beta1")
|
||||
WebhookVersion 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
|
||||
// WebhookRetryBackoff specifies the backoff parameters for the authorization webhook retry logic.
|
||||
// This allows us to configure the sleep time at each iteration and the maximum number of retries allowed
|
||||
// before we fail the webhook call in order to limit the fan out that ensues when the system is degraded.
|
||||
@ -66,12 +55,16 @@ type Config struct {
|
||||
|
||||
// Optional field, custom dial function used to connect to webhook
|
||||
CustomDial utilnet.DialFunc
|
||||
|
||||
// AuthorizationConfiguration stores the configuration for the Authorizer chain
|
||||
// It will deprecate most of the above flags when GA
|
||||
AuthorizationConfiguration *authzconfig.AuthorizationConfiguration
|
||||
}
|
||||
|
||||
// New returns the right sort of union of multiple authorizer.Authorizer objects
|
||||
// based on the authorizationMode or an error.
|
||||
func (config Config) New() (authorizer.Authorizer, authorizer.RuleResolver, error) {
|
||||
if len(config.AuthorizationModes) == 0 {
|
||||
if len(config.AuthorizationConfiguration.Authorizers) == 0 {
|
||||
return nil, nil, fmt.Errorf("at least one authorization mode must be passed")
|
||||
}
|
||||
|
||||
@ -84,10 +77,10 @@ func (config Config) New() (authorizer.Authorizer, authorizer.RuleResolver, erro
|
||||
superuserAuthorizer := authorizerfactory.NewPrivilegedGroups(user.SystemPrivilegedGroup)
|
||||
authorizers = append(authorizers, superuserAuthorizer)
|
||||
|
||||
for _, authorizationMode := range config.AuthorizationModes {
|
||||
for _, configuredAuthorizer := range config.AuthorizationConfiguration.Authorizers {
|
||||
// Keep cases in sync with constant list in k8s.io/kubernetes/pkg/kubeapiserver/authorizer/modes/modes.go.
|
||||
switch authorizationMode {
|
||||
case modes.ModeNode:
|
||||
switch configuredAuthorizer.Type {
|
||||
case authzconfig.AuthorizerType(modes.ModeNode):
|
||||
node.RegisterMetrics()
|
||||
graph := node.NewGraph()
|
||||
node.AddGraphEventHandlers(
|
||||
@ -101,33 +94,33 @@ func (config Config) New() (authorizer.Authorizer, authorizer.RuleResolver, erro
|
||||
authorizers = append(authorizers, nodeAuthorizer)
|
||||
ruleResolvers = append(ruleResolvers, nodeAuthorizer)
|
||||
|
||||
case modes.ModeAlwaysAllow:
|
||||
case authzconfig.AuthorizerType(modes.ModeAlwaysAllow):
|
||||
alwaysAllowAuthorizer := authorizerfactory.NewAlwaysAllowAuthorizer()
|
||||
authorizers = append(authorizers, alwaysAllowAuthorizer)
|
||||
ruleResolvers = append(ruleResolvers, alwaysAllowAuthorizer)
|
||||
case modes.ModeAlwaysDeny:
|
||||
case authzconfig.AuthorizerType(modes.ModeAlwaysDeny):
|
||||
alwaysDenyAuthorizer := authorizerfactory.NewAlwaysDenyAuthorizer()
|
||||
authorizers = append(authorizers, alwaysDenyAuthorizer)
|
||||
ruleResolvers = append(ruleResolvers, alwaysDenyAuthorizer)
|
||||
case modes.ModeABAC:
|
||||
case authzconfig.AuthorizerType(modes.ModeABAC):
|
||||
abacAuthorizer, err := abac.NewFromFile(config.PolicyFile)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
authorizers = append(authorizers, abacAuthorizer)
|
||||
ruleResolvers = append(ruleResolvers, abacAuthorizer)
|
||||
case modes.ModeWebhook:
|
||||
case authzconfig.AuthorizerType(modes.ModeWebhook):
|
||||
if config.WebhookRetryBackoff == nil {
|
||||
return nil, nil, errors.New("retry backoff parameters for authorization webhook has not been specified")
|
||||
}
|
||||
clientConfig, err := webhookutil.LoadKubeconfig(config.WebhookConfigFile, config.CustomDial)
|
||||
clientConfig, err := webhookutil.LoadKubeconfig(*configuredAuthorizer.Webhook.ConnectionInfo.KubeConfigFile, config.CustomDial)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
webhookAuthorizer, err := webhook.New(clientConfig,
|
||||
config.WebhookVersion,
|
||||
config.WebhookCacheAuthorizedTTL,
|
||||
config.WebhookCacheUnauthorizedTTL,
|
||||
configuredAuthorizer.Webhook.SubjectAccessReviewVersion,
|
||||
configuredAuthorizer.Webhook.AuthorizedTTL.Duration,
|
||||
configuredAuthorizer.Webhook.UnauthorizedTTL.Duration,
|
||||
*config.WebhookRetryBackoff,
|
||||
)
|
||||
if err != nil {
|
||||
@ -135,7 +128,7 @@ func (config Config) New() (authorizer.Authorizer, authorizer.RuleResolver, erro
|
||||
}
|
||||
authorizers = append(authorizers, webhookAuthorizer)
|
||||
ruleResolvers = append(ruleResolvers, webhookAuthorizer)
|
||||
case modes.ModeRBAC:
|
||||
case authzconfig.AuthorizerType(modes.ModeRBAC):
|
||||
rbacAuthorizer := rbac.New(
|
||||
&rbac.RoleGetter{Lister: config.VersionedInformerFactory.Rbac().V1().Roles().Lister()},
|
||||
&rbac.RoleBindingLister{Lister: config.VersionedInformerFactory.Rbac().V1().RoleBindings().Lister()},
|
||||
@ -145,7 +138,7 @@ func (config Config) New() (authorizer.Authorizer, authorizer.RuleResolver, erro
|
||||
authorizers = append(authorizers, rbacAuthorizer)
|
||||
ruleResolvers = append(ruleResolvers, rbacAuthorizer)
|
||||
default:
|
||||
return nil, nil, fmt.Errorf("unknown authorization mode %s specified", authorizationMode)
|
||||
return nil, nil, fmt.Errorf("unknown authorization mode %s specified", configuredAuthorizer.Type)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,14 +23,20 @@ import (
|
||||
|
||||
"github.com/spf13/pflag"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
authzconfig "k8s.io/apiserver/pkg/apis/apiserver"
|
||||
genericoptions "k8s.io/apiserver/pkg/server/options"
|
||||
versionedinformers "k8s.io/client-go/informers"
|
||||
"k8s.io/kubernetes/pkg/kubeapiserver/authorizer"
|
||||
authzmodes "k8s.io/kubernetes/pkg/kubeapiserver/authorizer/modes"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultWebhookName = "default"
|
||||
)
|
||||
|
||||
// BuiltInAuthorizationOptions contains all build-in authorization options for API Server
|
||||
type BuiltInAuthorizationOptions struct {
|
||||
Modes []string
|
||||
@ -62,7 +68,6 @@ func (o *BuiltInAuthorizationOptions) Validate() []error {
|
||||
return nil
|
||||
}
|
||||
var allErrors []error
|
||||
|
||||
if len(o.Modes) == 0 {
|
||||
allErrors = append(allErrors, fmt.Errorf("at least one authorization-mode must be passed"))
|
||||
}
|
||||
@ -125,15 +130,54 @@ func (o *BuiltInAuthorizationOptions) AddFlags(fs *pflag.FlagSet) {
|
||||
}
|
||||
|
||||
// ToAuthorizationConfig convert BuiltInAuthorizationOptions to authorizer.Config
|
||||
func (o *BuiltInAuthorizationOptions) ToAuthorizationConfig(versionedInformerFactory versionedinformers.SharedInformerFactory) authorizer.Config {
|
||||
return authorizer.Config{
|
||||
AuthorizationModes: o.Modes,
|
||||
PolicyFile: o.PolicyFile,
|
||||
WebhookConfigFile: o.WebhookConfigFile,
|
||||
WebhookVersion: o.WebhookVersion,
|
||||
WebhookCacheAuthorizedTTL: o.WebhookCacheAuthorizedTTL,
|
||||
WebhookCacheUnauthorizedTTL: o.WebhookCacheUnauthorizedTTL,
|
||||
VersionedInformerFactory: versionedInformerFactory,
|
||||
WebhookRetryBackoff: o.WebhookRetryBackoff,
|
||||
func (o *BuiltInAuthorizationOptions) ToAuthorizationConfig(versionedInformerFactory versionedinformers.SharedInformerFactory) (authorizer.Config, error) {
|
||||
|
||||
authzConfiguration, err := o.buildAuthorizationConfiguration()
|
||||
if err != nil {
|
||||
return authorizer.Config{}, fmt.Errorf("failed to build authorization config: %s", err)
|
||||
}
|
||||
|
||||
return authorizer.Config{
|
||||
PolicyFile: o.PolicyFile,
|
||||
VersionedInformerFactory: versionedInformerFactory,
|
||||
WebhookRetryBackoff: o.WebhookRetryBackoff,
|
||||
|
||||
AuthorizationConfiguration: authzConfiguration,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// buildAuthorizationConfiguration converts existing flags to the AuthorizationConfiguration format
|
||||
func (o *BuiltInAuthorizationOptions) buildAuthorizationConfiguration() (*authzconfig.AuthorizationConfiguration, error) {
|
||||
var authorizers []authzconfig.AuthorizerConfiguration
|
||||
|
||||
if len(o.Modes) != sets.NewString(o.Modes...).Len() {
|
||||
return nil, fmt.Errorf("modes should not be repeated in --authorization-mode")
|
||||
}
|
||||
|
||||
for _, mode := range o.Modes {
|
||||
switch mode {
|
||||
case authzmodes.ModeWebhook:
|
||||
authorizers = append(authorizers, authzconfig.AuthorizerConfiguration{
|
||||
Type: authzconfig.TypeWebhook,
|
||||
Webhook: &authzconfig.WebhookConfiguration{
|
||||
Name: defaultWebhookName,
|
||||
AuthorizedTTL: metav1.Duration{Duration: o.WebhookCacheAuthorizedTTL},
|
||||
UnauthorizedTTL: metav1.Duration{Duration: o.WebhookCacheUnauthorizedTTL},
|
||||
// Timeout and FailurePolicy are required for the new configuration.
|
||||
// Setting these two implicitly to preserve backward compatibility.
|
||||
Timeout: metav1.Duration{Duration: 30 * time.Second},
|
||||
FailurePolicy: authzconfig.FailurePolicyNoOpinion,
|
||||
SubjectAccessReviewVersion: o.WebhookVersion,
|
||||
ConnectionInfo: authzconfig.WebhookConnectionInfo{
|
||||
Type: authzconfig.AuthorizationWebhookConnectionInfoTypeKubeConfig,
|
||||
KubeConfigFile: &o.WebhookConfigFile,
|
||||
},
|
||||
},
|
||||
})
|
||||
default:
|
||||
authorizers = append(authorizers, authzconfig.AuthorizerConfiguration{Type: authzconfig.AuthorizerType(mode)})
|
||||
}
|
||||
}
|
||||
|
||||
return &authzconfig.AuthorizationConfiguration{Authorizers: authorizers}, nil
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user