mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-24 20:24:09 +00:00
start kubeapiserver package for sharing between kubeapiserver and federation
This commit is contained in:
parent
0483548a93
commit
a3564c0aa8
@ -30,7 +30,6 @@ go_library(
|
|||||||
"//pkg/controller/serviceaccount:go_default_library",
|
"//pkg/controller/serviceaccount:go_default_library",
|
||||||
"//pkg/generated/openapi:go_default_library",
|
"//pkg/generated/openapi:go_default_library",
|
||||||
"//pkg/genericapiserver:go_default_library",
|
"//pkg/genericapiserver:go_default_library",
|
||||||
"//pkg/genericapiserver/authorizer:go_default_library",
|
|
||||||
"//pkg/genericapiserver/filters:go_default_library",
|
"//pkg/genericapiserver/filters:go_default_library",
|
||||||
"//pkg/master:go_default_library",
|
"//pkg/master:go_default_library",
|
||||||
"//pkg/registry/cachesize:go_default_library",
|
"//pkg/registry/cachesize:go_default_library",
|
||||||
|
@ -19,6 +19,7 @@ go_library(
|
|||||||
"//pkg/api:go_default_library",
|
"//pkg/api:go_default_library",
|
||||||
"//pkg/api/validation:go_default_library",
|
"//pkg/api/validation:go_default_library",
|
||||||
"//pkg/genericapiserver/options:go_default_library",
|
"//pkg/genericapiserver/options:go_default_library",
|
||||||
|
"//pkg/kubeapiserver/options:go_default_library",
|
||||||
"//pkg/kubelet/client:go_default_library",
|
"//pkg/kubelet/client:go_default_library",
|
||||||
"//pkg/master/ports:go_default_library",
|
"//pkg/master/ports:go_default_library",
|
||||||
"//pkg/util/net:go_default_library",
|
"//pkg/util/net:go_default_library",
|
||||||
|
@ -24,6 +24,7 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
"k8s.io/kubernetes/pkg/api/validation"
|
"k8s.io/kubernetes/pkg/api/validation"
|
||||||
genericoptions "k8s.io/kubernetes/pkg/genericapiserver/options"
|
genericoptions "k8s.io/kubernetes/pkg/genericapiserver/options"
|
||||||
|
kubeoptions "k8s.io/kubernetes/pkg/kubeapiserver/options"
|
||||||
kubeletclient "k8s.io/kubernetes/pkg/kubelet/client"
|
kubeletclient "k8s.io/kubernetes/pkg/kubelet/client"
|
||||||
"k8s.io/kubernetes/pkg/master/ports"
|
"k8s.io/kubernetes/pkg/master/ports"
|
||||||
utilnet "k8s.io/kubernetes/pkg/util/net"
|
utilnet "k8s.io/kubernetes/pkg/util/net"
|
||||||
@ -41,7 +42,7 @@ type ServerRunOptions struct {
|
|||||||
SecureServing *genericoptions.SecureServingOptions
|
SecureServing *genericoptions.SecureServingOptions
|
||||||
InsecureServing *genericoptions.ServingOptions
|
InsecureServing *genericoptions.ServingOptions
|
||||||
Authentication *genericoptions.BuiltInAuthenticationOptions
|
Authentication *genericoptions.BuiltInAuthenticationOptions
|
||||||
Authorization *genericoptions.BuiltInAuthorizationOptions
|
Authorization *kubeoptions.BuiltInAuthorizationOptions
|
||||||
|
|
||||||
AllowPrivileged bool
|
AllowPrivileged bool
|
||||||
EventTTL time.Duration
|
EventTTL time.Duration
|
||||||
@ -63,7 +64,7 @@ func NewServerRunOptions() *ServerRunOptions {
|
|||||||
SecureServing: genericoptions.NewSecureServingOptions(),
|
SecureServing: genericoptions.NewSecureServingOptions(),
|
||||||
InsecureServing: genericoptions.NewInsecureServingOptions(),
|
InsecureServing: genericoptions.NewInsecureServingOptions(),
|
||||||
Authentication: genericoptions.NewBuiltInAuthenticationOptions().WithAll(),
|
Authentication: genericoptions.NewBuiltInAuthenticationOptions().WithAll(),
|
||||||
Authorization: genericoptions.NewBuiltInAuthorizationOptions(),
|
Authorization: kubeoptions.NewBuiltInAuthorizationOptions(),
|
||||||
|
|
||||||
EventTTL: 1 * time.Hour,
|
EventTTL: 1 * time.Hour,
|
||||||
MasterCount: 1,
|
MasterCount: 1,
|
||||||
|
@ -49,7 +49,6 @@ import (
|
|||||||
serviceaccountcontroller "k8s.io/kubernetes/pkg/controller/serviceaccount"
|
serviceaccountcontroller "k8s.io/kubernetes/pkg/controller/serviceaccount"
|
||||||
generatedopenapi "k8s.io/kubernetes/pkg/generated/openapi"
|
generatedopenapi "k8s.io/kubernetes/pkg/generated/openapi"
|
||||||
"k8s.io/kubernetes/pkg/genericapiserver"
|
"k8s.io/kubernetes/pkg/genericapiserver"
|
||||||
"k8s.io/kubernetes/pkg/genericapiserver/authorizer"
|
|
||||||
"k8s.io/kubernetes/pkg/genericapiserver/filters"
|
"k8s.io/kubernetes/pkg/genericapiserver/filters"
|
||||||
"k8s.io/kubernetes/pkg/master"
|
"k8s.io/kubernetes/pkg/master"
|
||||||
"k8s.io/kubernetes/pkg/registry/cachesize"
|
"k8s.io/kubernetes/pkg/registry/cachesize"
|
||||||
@ -261,7 +260,7 @@ func Run(s *options.ServerRunOptions) error {
|
|||||||
sharedInformers := informers.NewSharedInformerFactory(nil, client, 10*time.Minute)
|
sharedInformers := informers.NewSharedInformerFactory(nil, client, 10*time.Minute)
|
||||||
|
|
||||||
authorizationConfig := s.Authorization.ToAuthorizationConfig(sharedInformers)
|
authorizationConfig := s.Authorization.ToAuthorizationConfig(sharedInformers)
|
||||||
apiAuthorizer, err := authorizer.NewAuthorizerFromAuthorizationConfig(authorizationConfig)
|
apiAuthorizer, err := authorizationConfig.New()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("invalid Authorization Config: %v", err)
|
return fmt.Errorf("invalid Authorization Config: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,6 @@ go_library(
|
|||||||
"//pkg/controller/informers:go_default_library",
|
"//pkg/controller/informers:go_default_library",
|
||||||
"//pkg/generated/openapi:go_default_library",
|
"//pkg/generated/openapi:go_default_library",
|
||||||
"//pkg/genericapiserver:go_default_library",
|
"//pkg/genericapiserver:go_default_library",
|
||||||
"//pkg/genericapiserver/authorizer:go_default_library",
|
|
||||||
"//pkg/genericapiserver/filters:go_default_library",
|
"//pkg/genericapiserver/filters:go_default_library",
|
||||||
"//pkg/registry/batch/job/etcd:go_default_library",
|
"//pkg/registry/batch/job/etcd:go_default_library",
|
||||||
"//pkg/registry/cachesize:go_default_library",
|
"//pkg/registry/cachesize:go_default_library",
|
||||||
|
@ -16,6 +16,7 @@ go_library(
|
|||||||
tags = ["automanaged"],
|
tags = ["automanaged"],
|
||||||
deps = [
|
deps = [
|
||||||
"//pkg/genericapiserver/options:go_default_library",
|
"//pkg/genericapiserver/options:go_default_library",
|
||||||
|
"//pkg/kubeapiserver/options:go_default_library",
|
||||||
"//vendor:github.com/spf13/pflag",
|
"//vendor:github.com/spf13/pflag",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
@ -21,6 +21,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
genericoptions "k8s.io/kubernetes/pkg/genericapiserver/options"
|
genericoptions "k8s.io/kubernetes/pkg/genericapiserver/options"
|
||||||
|
kubeoptions "k8s.io/kubernetes/pkg/kubeapiserver/options"
|
||||||
|
|
||||||
"github.com/spf13/pflag"
|
"github.com/spf13/pflag"
|
||||||
)
|
)
|
||||||
@ -32,7 +33,7 @@ type ServerRunOptions struct {
|
|||||||
SecureServing *genericoptions.SecureServingOptions
|
SecureServing *genericoptions.SecureServingOptions
|
||||||
InsecureServing *genericoptions.ServingOptions
|
InsecureServing *genericoptions.ServingOptions
|
||||||
Authentication *genericoptions.BuiltInAuthenticationOptions
|
Authentication *genericoptions.BuiltInAuthenticationOptions
|
||||||
Authorization *genericoptions.BuiltInAuthorizationOptions
|
Authorization *kubeoptions.BuiltInAuthorizationOptions
|
||||||
|
|
||||||
EventTTL time.Duration
|
EventTTL time.Duration
|
||||||
}
|
}
|
||||||
@ -45,7 +46,7 @@ func NewServerRunOptions() *ServerRunOptions {
|
|||||||
SecureServing: genericoptions.NewSecureServingOptions(),
|
SecureServing: genericoptions.NewSecureServingOptions(),
|
||||||
InsecureServing: genericoptions.NewInsecureServingOptions(),
|
InsecureServing: genericoptions.NewInsecureServingOptions(),
|
||||||
Authentication: genericoptions.NewBuiltInAuthenticationOptions().WithAll(),
|
Authentication: genericoptions.NewBuiltInAuthenticationOptions().WithAll(),
|
||||||
Authorization: genericoptions.NewBuiltInAuthorizationOptions(),
|
Authorization: kubeoptions.NewBuiltInAuthorizationOptions(),
|
||||||
|
|
||||||
EventTTL: 1 * time.Hour,
|
EventTTL: 1 * time.Hour,
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,6 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/controller/informers"
|
"k8s.io/kubernetes/pkg/controller/informers"
|
||||||
"k8s.io/kubernetes/pkg/generated/openapi"
|
"k8s.io/kubernetes/pkg/generated/openapi"
|
||||||
"k8s.io/kubernetes/pkg/genericapiserver"
|
"k8s.io/kubernetes/pkg/genericapiserver"
|
||||||
"k8s.io/kubernetes/pkg/genericapiserver/authorizer"
|
|
||||||
"k8s.io/kubernetes/pkg/genericapiserver/filters"
|
"k8s.io/kubernetes/pkg/genericapiserver/filters"
|
||||||
"k8s.io/kubernetes/pkg/registry/cachesize"
|
"k8s.io/kubernetes/pkg/registry/cachesize"
|
||||||
"k8s.io/kubernetes/pkg/registry/generic"
|
"k8s.io/kubernetes/pkg/registry/generic"
|
||||||
@ -151,8 +150,8 @@ func Run(s *options.ServerRunOptions) error {
|
|||||||
}
|
}
|
||||||
sharedInformers := informers.NewSharedInformerFactory(nil, client, 10*time.Minute)
|
sharedInformers := informers.NewSharedInformerFactory(nil, client, 10*time.Minute)
|
||||||
|
|
||||||
authorizerconfig := s.Authorization.ToAuthorizationConfig(sharedInformers)
|
authorizationConfig := s.Authorization.ToAuthorizationConfig(sharedInformers)
|
||||||
apiAuthorizer, err := authorizer.NewAuthorizerFromAuthorizationConfig(authorizerconfig)
|
apiAuthorizer, err := authorizationConfig.New()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("invalid Authorization Config: %v", err)
|
return fmt.Errorf("invalid Authorization Config: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -17,11 +17,7 @@ go_library(
|
|||||||
tags = ["automanaged"],
|
tags = ["automanaged"],
|
||||||
deps = [
|
deps = [
|
||||||
"//pkg/auth/authorizer:go_default_library",
|
"//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/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",
|
"//plugin/pkg/auth/authorizer/webhook:go_default_library",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
@ -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) {
|
func TestPrivilegedGroupAuthorizer(t *testing.T) {
|
||||||
auth := NewPrivilegedGroups("allow-01", "allow-01")
|
auth := NewPrivilegedGroups("allow-01", "allow-01")
|
||||||
|
|
||||||
|
@ -18,23 +18,8 @@ package authorizer
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/auth/authorizer"
|
"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
|
// alwaysAllowAuthorizer is an implementation of authorizer.Attributes
|
||||||
@ -100,96 +85,3 @@ func NewPrivilegedGroups(groups ...string) *privilegedGroupAuthorizer {
|
|||||||
groups: groups,
|
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
|
|
||||||
}
|
|
||||||
|
@ -29,7 +29,6 @@ go_library(
|
|||||||
"//pkg/client/restclient:go_default_library",
|
"//pkg/client/restclient:go_default_library",
|
||||||
"//pkg/client/unversioned/clientcmd:go_default_library",
|
"//pkg/client/unversioned/clientcmd:go_default_library",
|
||||||
"//pkg/cloudprovider:go_default_library",
|
"//pkg/cloudprovider:go_default_library",
|
||||||
"//pkg/controller/informers:go_default_library",
|
|
||||||
"//pkg/genericapiserver/authorizer:go_default_library",
|
"//pkg/genericapiserver/authorizer:go_default_library",
|
||||||
"//pkg/runtime/schema:go_default_library",
|
"//pkg/runtime/schema:go_default_library",
|
||||||
"//pkg/storage/storagebackend:go_default_library",
|
"//pkg/storage/storagebackend:go_default_library",
|
||||||
|
@ -17,7 +17,6 @@ limitations under the License.
|
|||||||
package options
|
package options
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/spf13/pflag"
|
"github.com/spf13/pflag"
|
||||||
@ -25,76 +24,9 @@ import (
|
|||||||
authorizationclient "k8s.io/kubernetes/pkg/client/clientset_generated/clientset/typed/authorization/v1beta1"
|
authorizationclient "k8s.io/kubernetes/pkg/client/clientset_generated/clientset/typed/authorization/v1beta1"
|
||||||
"k8s.io/kubernetes/pkg/client/restclient"
|
"k8s.io/kubernetes/pkg/client/restclient"
|
||||||
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
|
"k8s.io/kubernetes/pkg/client/unversioned/clientcmd"
|
||||||
"k8s.io/kubernetes/pkg/controller/informers"
|
|
||||||
"k8s.io/kubernetes/pkg/genericapiserver/authorizer"
|
"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
|
// DelegatingAuthorizationOptions provides an easy way for composing API servers to delegate their authorization to
|
||||||
// the root kube API server
|
// the root kube API server
|
||||||
type DelegatingAuthorizationOptions struct {
|
type DelegatingAuthorizationOptions struct {
|
||||||
|
14
pkg/kubeapiserver/BUILD
Normal file
14
pkg/kubeapiserver/BUILD
Normal 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"],
|
||||||
|
)
|
35
pkg/kubeapiserver/authorizer/BUILD
Normal file
35
pkg/kubeapiserver/authorizer/BUILD
Normal 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",
|
||||||
|
],
|
||||||
|
)
|
131
pkg/kubeapiserver/authorizer/config.go
Normal file
131
pkg/kubeapiserver/authorizer/config.go
Normal 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
|
||||||
|
}
|
100
pkg/kubeapiserver/authorizer/config_test.go
Normal file
100
pkg/kubeapiserver/authorizer/config_test.go
Normal 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
21
pkg/kubeapiserver/doc.go
Normal 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
|
19
pkg/kubeapiserver/options/BUILD
Normal file
19
pkg/kubeapiserver/options/BUILD
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
package(default_visibility = ["//visibility:public"])
|
||||||
|
|
||||||
|
licenses(["notice"])
|
||||||
|
|
||||||
|
load(
|
||||||
|
"@io_bazel_rules_go//go:def.bzl",
|
||||||
|
"go_library",
|
||||||
|
)
|
||||||
|
|
||||||
|
go_library(
|
||||||
|
name = "go_default_library",
|
||||||
|
srcs = ["authorization.go"],
|
||||||
|
tags = ["automanaged"],
|
||||||
|
deps = [
|
||||||
|
"//pkg/controller/informers:go_default_library",
|
||||||
|
"//pkg/kubeapiserver/authorizer:go_default_library",
|
||||||
|
"//vendor:github.com/spf13/pflag",
|
||||||
|
],
|
||||||
|
)
|
93
pkg/kubeapiserver/options/authorization.go
Normal file
93
pkg/kubeapiserver/options/authorization.go
Normal 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,
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user