mirror of https://github.com/k3s-io/k3s
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
133 lines
5.0 KiB
133 lines
5.0 KiB
/*
|
|
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 (
|
|
"fmt"
|
|
"time"
|
|
|
|
utilnet "k8s.io/apimachinery/pkg/util/net"
|
|
"k8s.io/apiserver/pkg/authorization/authorizer"
|
|
"k8s.io/apiserver/pkg/authorization/authorizerfactory"
|
|
"k8s.io/apiserver/pkg/authorization/union"
|
|
"k8s.io/apiserver/plugin/pkg/authorizer/webhook"
|
|
versionedinformers "k8s.io/client-go/informers"
|
|
"k8s.io/kubernetes/pkg/auth/authorizer/abac"
|
|
"k8s.io/kubernetes/pkg/auth/nodeidentifier"
|
|
"k8s.io/kubernetes/pkg/kubeapiserver/authorizer/modes"
|
|
"k8s.io/kubernetes/plugin/pkg/auth/authorizer/node"
|
|
"k8s.io/kubernetes/plugin/pkg/auth/authorizer/rbac"
|
|
"k8s.io/kubernetes/plugin/pkg/auth/authorizer/rbac/bootstrappolicy"
|
|
)
|
|
|
|
// 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.
|
|
PolicyFile string
|
|
|
|
// 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
|
|
|
|
VersionedInformerFactory versionedinformers.SharedInformerFactory
|
|
|
|
// Optional field, custom dial function used to connect to webhook
|
|
CustomDial utilnet.DialFunc
|
|
}
|
|
|
|
// 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 {
|
|
return nil, nil, fmt.Errorf("at least one authorization mode must be passed")
|
|
}
|
|
|
|
var (
|
|
authorizers []authorizer.Authorizer
|
|
ruleResolvers []authorizer.RuleResolver
|
|
)
|
|
|
|
for _, authorizationMode := range config.AuthorizationModes {
|
|
// Keep cases in sync with constant list in k8s.io/kubernetes/pkg/kubeapiserver/authorizer/modes/modes.go.
|
|
switch authorizationMode {
|
|
case modes.ModeNode:
|
|
graph := node.NewGraph()
|
|
node.AddGraphEventHandlers(
|
|
graph,
|
|
config.VersionedInformerFactory.Core().V1().Nodes(),
|
|
config.VersionedInformerFactory.Core().V1().Pods(),
|
|
config.VersionedInformerFactory.Core().V1().PersistentVolumes(),
|
|
config.VersionedInformerFactory.Storage().V1().VolumeAttachments(),
|
|
)
|
|
nodeAuthorizer := node.NewAuthorizer(graph, nodeidentifier.NewDefaultNodeIdentifier(), bootstrappolicy.NodeRules())
|
|
authorizers = append(authorizers, nodeAuthorizer)
|
|
ruleResolvers = append(ruleResolvers, nodeAuthorizer)
|
|
|
|
case modes.ModeAlwaysAllow:
|
|
alwaysAllowAuthorizer := authorizerfactory.NewAlwaysAllowAuthorizer()
|
|
authorizers = append(authorizers, alwaysAllowAuthorizer)
|
|
ruleResolvers = append(ruleResolvers, alwaysAllowAuthorizer)
|
|
case modes.ModeAlwaysDeny:
|
|
alwaysDenyAuthorizer := authorizerfactory.NewAlwaysDenyAuthorizer()
|
|
authorizers = append(authorizers, alwaysDenyAuthorizer)
|
|
ruleResolvers = append(ruleResolvers, alwaysDenyAuthorizer)
|
|
case 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:
|
|
webhookAuthorizer, err := webhook.New(config.WebhookConfigFile,
|
|
config.WebhookVersion,
|
|
config.WebhookCacheAuthorizedTTL,
|
|
config.WebhookCacheUnauthorizedTTL,
|
|
config.CustomDial)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
authorizers = append(authorizers, webhookAuthorizer)
|
|
ruleResolvers = append(ruleResolvers, webhookAuthorizer)
|
|
case modes.ModeRBAC:
|
|
rbacAuthorizer := rbac.New(
|
|
&rbac.RoleGetter{Lister: config.VersionedInformerFactory.Rbac().V1().Roles().Lister()},
|
|
&rbac.RoleBindingLister{Lister: config.VersionedInformerFactory.Rbac().V1().RoleBindings().Lister()},
|
|
&rbac.ClusterRoleGetter{Lister: config.VersionedInformerFactory.Rbac().V1().ClusterRoles().Lister()},
|
|
&rbac.ClusterRoleBindingLister{Lister: config.VersionedInformerFactory.Rbac().V1().ClusterRoleBindings().Lister()},
|
|
)
|
|
authorizers = append(authorizers, rbacAuthorizer)
|
|
ruleResolvers = append(ruleResolvers, rbacAuthorizer)
|
|
default:
|
|
return nil, nil, fmt.Errorf("unknown authorization mode %s specified", authorizationMode)
|
|
}
|
|
}
|
|
|
|
return union.New(authorizers...), union.NewRuleResolvers(ruleResolvers...), nil
|
|
}
|