Move the authorization mode constants into a separate package

This commit is contained in:
Lucas Käldström 2017-02-23 15:27:16 +02:00
parent 1320021aaf
commit ab344da565
No known key found for this signature in database
GPG Key ID: 3FA3783D77751514
9 changed files with 145 additions and 29 deletions

View File

@ -16,6 +16,7 @@ go_test(
], ],
library = ":go_default_library", library = ":go_default_library",
tags = ["automanaged"], tags = ["automanaged"],
deps = ["//pkg/kubeapiserver/authorizer/modes:go_default_library"],
) )
go_library( go_library(
@ -25,6 +26,7 @@ go_library(
deps = [ deps = [
"//pkg/auth/authorizer/abac:go_default_library", "//pkg/auth/authorizer/abac:go_default_library",
"//pkg/controller/informers:go_default_library", "//pkg/controller/informers:go_default_library",
"//pkg/kubeapiserver/authorizer/modes:go_default_library",
"//plugin/pkg/auth/authorizer/rbac:go_default_library", "//plugin/pkg/auth/authorizer/rbac:go_default_library",
"//vendor:k8s.io/apiserver/pkg/authorization/authorizer", "//vendor:k8s.io/apiserver/pkg/authorization/authorizer",
"//vendor:k8s.io/apiserver/pkg/authorization/authorizerfactory", "//vendor:k8s.io/apiserver/pkg/authorization/authorizerfactory",
@ -42,6 +44,9 @@ filegroup(
filegroup( filegroup(
name = "all-srcs", name = "all-srcs",
srcs = [":package-srcs"], srcs = [
":package-srcs",
"//pkg/kubeapiserver/authorizer/modes:all-srcs",
],
tags = ["automanaged"], tags = ["automanaged"],
) )

View File

@ -27,17 +27,10 @@ import (
"k8s.io/apiserver/plugin/pkg/authorizer/webhook" "k8s.io/apiserver/plugin/pkg/authorizer/webhook"
"k8s.io/kubernetes/pkg/auth/authorizer/abac" "k8s.io/kubernetes/pkg/auth/authorizer/abac"
"k8s.io/kubernetes/pkg/controller/informers" "k8s.io/kubernetes/pkg/controller/informers"
"k8s.io/kubernetes/pkg/kubeapiserver/authorizer/modes"
"k8s.io/kubernetes/plugin/pkg/auth/authorizer/rbac" "k8s.io/kubernetes/plugin/pkg/auth/authorizer/rbac"
) )
const (
ModeAlwaysAllow string = "AlwaysAllow"
ModeAlwaysDeny string = "AlwaysDeny"
ModeABAC string = "ABAC"
ModeWebhook string = "Webhook"
ModeRBAC string = "RBAC"
)
type AuthorizationConfig struct { type AuthorizationConfig struct {
AuthorizationModes []string AuthorizationModes []string
@ -79,11 +72,11 @@ func (config AuthorizationConfig) New() (authorizer.Authorizer, error) {
} }
// Keep cases in sync with constant list above. // Keep cases in sync with constant list above.
switch authorizationMode { switch authorizationMode {
case ModeAlwaysAllow: case modes.ModeAlwaysAllow:
authorizers = append(authorizers, authorizerfactory.NewAlwaysAllowAuthorizer()) authorizers = append(authorizers, authorizerfactory.NewAlwaysAllowAuthorizer())
case ModeAlwaysDeny: case modes.ModeAlwaysDeny:
authorizers = append(authorizers, authorizerfactory.NewAlwaysDenyAuthorizer()) authorizers = append(authorizers, authorizerfactory.NewAlwaysDenyAuthorizer())
case ModeABAC: case modes.ModeABAC:
if config.PolicyFile == "" { if config.PolicyFile == "" {
return nil, errors.New("ABAC's authorization policy file not passed") return nil, errors.New("ABAC's authorization policy file not passed")
} }
@ -92,7 +85,7 @@ func (config AuthorizationConfig) New() (authorizer.Authorizer, error) {
return nil, err return nil, err
} }
authorizers = append(authorizers, abacAuthorizer) authorizers = append(authorizers, abacAuthorizer)
case ModeWebhook: case modes.ModeWebhook:
if config.WebhookConfigFile == "" { if config.WebhookConfigFile == "" {
return nil, errors.New("Webhook's configuration file not passed") return nil, errors.New("Webhook's configuration file not passed")
} }
@ -103,7 +96,7 @@ func (config AuthorizationConfig) New() (authorizer.Authorizer, error) {
return nil, err return nil, err
} }
authorizers = append(authorizers, webhookAuthorizer) authorizers = append(authorizers, webhookAuthorizer)
case ModeRBAC: case modes.ModeRBAC:
rbacAuthorizer := rbac.New( rbacAuthorizer := rbac.New(
config.InformerFactory.Roles().Lister(), config.InformerFactory.Roles().Lister(),
config.InformerFactory.RoleBindings().Lister(), config.InformerFactory.RoleBindings().Lister(),
@ -117,13 +110,13 @@ func (config AuthorizationConfig) New() (authorizer.Authorizer, error) {
authorizerMap[authorizationMode] = true authorizerMap[authorizationMode] = true
} }
if !authorizerMap[ModeABAC] && config.PolicyFile != "" { if !authorizerMap[modes.ModeABAC] && config.PolicyFile != "" {
return nil, errors.New("Cannot specify --authorization-policy-file without mode ABAC") return nil, errors.New("Cannot specify --authorization-policy-file without mode ABAC")
} }
if !authorizerMap[ModeWebhook] && config.WebhookConfigFile != "" { if !authorizerMap[modes.ModeWebhook] && config.WebhookConfigFile != "" {
return nil, errors.New("Cannot specify --authorization-webhook-config-file without mode Webhook") return nil, errors.New("Cannot specify --authorization-webhook-config-file without mode Webhook")
} }
if !authorizerMap[ModeRBAC] && config.RBACSuperUser != "" { if !authorizerMap[modes.ModeRBAC] && config.RBACSuperUser != "" {
return nil, errors.New("Cannot specify --authorization-rbac-super-user without mode RBAC") return nil, errors.New("Cannot specify --authorization-rbac-super-user without mode RBAC")
} }

View File

@ -17,6 +17,7 @@ limitations under the License.
package authorizer package authorizer
import ( import (
"k8s.io/kubernetes/pkg/kubeapiserver/authorizer/modes"
"testing" "testing"
) )
@ -39,19 +40,19 @@ func TestNew(t *testing.T) {
{ {
// ModeAlwaysAllow and ModeAlwaysDeny should return without authorizationPolicyFile // ModeAlwaysAllow and ModeAlwaysDeny should return without authorizationPolicyFile
// but error if one is given // but error if one is given
config: AuthorizationConfig{AuthorizationModes: []string{ModeAlwaysAllow, ModeAlwaysDeny}}, config: AuthorizationConfig{AuthorizationModes: []string{modes.ModeAlwaysAllow, modes.ModeAlwaysDeny}},
msg: "returned an error for valid config", msg: "returned an error for valid config",
}, },
{ {
// ModeABAC requires a policy file // ModeABAC requires a policy file
config: AuthorizationConfig{AuthorizationModes: []string{ModeAlwaysAllow, ModeAlwaysDeny, ModeABAC}}, config: AuthorizationConfig{AuthorizationModes: []string{modes.ModeAlwaysAllow, modes.ModeAlwaysDeny, modes.ModeABAC}},
wantErr: true, wantErr: true,
msg: "specifying ABAC with no policy file should return an error", msg: "specifying ABAC with no policy file should return an error",
}, },
{ {
// ModeABAC should not error if a valid policy path is provided // ModeABAC should not error if a valid policy path is provided
config: AuthorizationConfig{ config: AuthorizationConfig{
AuthorizationModes: []string{ModeAlwaysAllow, ModeAlwaysDeny, ModeABAC}, AuthorizationModes: []string{modes.ModeAlwaysAllow, modes.ModeAlwaysDeny, modes.ModeABAC},
PolicyFile: examplePolicyFile, PolicyFile: examplePolicyFile,
}, },
msg: "errored while using a valid policy file", msg: "errored while using a valid policy file",
@ -60,7 +61,7 @@ func TestNew(t *testing.T) {
// Authorization Policy file cannot be used without ModeABAC // Authorization Policy file cannot be used without ModeABAC
config: AuthorizationConfig{ config: AuthorizationConfig{
AuthorizationModes: []string{ModeAlwaysAllow, ModeAlwaysDeny}, AuthorizationModes: []string{modes.ModeAlwaysAllow, modes.ModeAlwaysDeny},
PolicyFile: examplePolicyFile, PolicyFile: examplePolicyFile,
}, },
wantErr: true, wantErr: true,
@ -74,14 +75,14 @@ func TestNew(t *testing.T) {
}, },
{ {
// ModeWebhook requires at minimum a target. // ModeWebhook requires at minimum a target.
config: AuthorizationConfig{AuthorizationModes: []string{ModeWebhook}}, config: AuthorizationConfig{AuthorizationModes: []string{modes.ModeWebhook}},
wantErr: true, wantErr: true,
msg: "should have errored when config was empty with ModeWebhook", msg: "should have errored when config was empty with ModeWebhook",
}, },
{ {
// Cannot provide webhook flags without ModeWebhook // Cannot provide webhook flags without ModeWebhook
config: AuthorizationConfig{ config: AuthorizationConfig{
AuthorizationModes: []string{ModeAlwaysAllow}, AuthorizationModes: []string{modes.ModeAlwaysAllow},
WebhookConfigFile: "authz_webhook_config.yml", WebhookConfigFile: "authz_webhook_config.yml",
}, },
wantErr: true, wantErr: true,

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 = ["modes_test.go"],
library = ":go_default_library",
tags = ["automanaged"],
)
go_library(
name = "go_default_library",
srcs = ["modes.go"],
tags = ["automanaged"],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
)

View File

@ -0,0 +1,37 @@
/*
Copyright 2017 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 modes
const (
ModeAlwaysAllow string = "AlwaysAllow"
ModeAlwaysDeny string = "AlwaysDeny"
ModeABAC string = "ABAC"
ModeWebhook string = "Webhook"
ModeRBAC string = "RBAC"
)
var AuthorizationModeChoices = []string{ModeAlwaysAllow, ModeAlwaysDeny, ModeABAC, ModeWebhook, ModeRBAC}
// IsValidAuthorizationMode returns true if the given authorization mode is a valid one for the apiserver
func IsValidAuthorizationMode(authzMode string) bool {
for _, validMode := range AuthorizationModeChoices {
if authzMode == validMode {
return true
}
}
return false
}

View File

@ -0,0 +1,45 @@
/*
Copyright 2017 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 modes
import "testing"
func TestIsValidAuthorizationMode(t *testing.T) {
var tests = []struct {
authzMode string
expected bool
}{
{"", false},
{"rBAC", false}, // not supported
{"falsy value", false}, // not supported
{"RBAC", true}, // supported
{"ABAC", true}, // supported
{"Webhook", true}, // supported
{"AlwaysAllow", true}, // supported
{"AlwaysDeny", true}, // supported
}
for _, rt := range tests {
actual := IsValidAuthorizationMode(rt.authzMode)
if actual != rt.expected {
t.Errorf(
"failed ValidAuthorizationMode:\n\texpected: %t\n\t actual: %t",
rt.expected,
actual,
)
}
}
}

View File

@ -25,6 +25,7 @@ go_library(
"//pkg/controller/informers:go_default_library", "//pkg/controller/informers:go_default_library",
"//pkg/kubeapiserver/authenticator:go_default_library", "//pkg/kubeapiserver/authenticator:go_default_library",
"//pkg/kubeapiserver/authorizer:go_default_library", "//pkg/kubeapiserver/authorizer:go_default_library",
"//pkg/kubeapiserver/authorizer/modes:go_default_library",
"//vendor:github.com/golang/glog", "//vendor:github.com/golang/glog",
"//vendor:github.com/spf13/pflag", "//vendor:github.com/spf13/pflag",
"//vendor:k8s.io/apimachinery/pkg/runtime/schema", "//vendor:k8s.io/apimachinery/pkg/runtime/schema",

View File

@ -27,7 +27,7 @@ import (
genericapiserver "k8s.io/apiserver/pkg/server" genericapiserver "k8s.io/apiserver/pkg/server"
genericoptions "k8s.io/apiserver/pkg/server/options" genericoptions "k8s.io/apiserver/pkg/server/options"
"k8s.io/kubernetes/pkg/kubeapiserver/authenticator" "k8s.io/kubernetes/pkg/kubeapiserver/authenticator"
"k8s.io/kubernetes/pkg/kubeapiserver/authorizer" authzmodes "k8s.io/kubernetes/pkg/kubeapiserver/authorizer/modes"
) )
type BuiltInAuthenticationOptions struct { type BuiltInAuthenticationOptions struct {
@ -353,7 +353,7 @@ func (o *BuiltInAuthenticationOptions) ApplyAuthorization(authorization *BuiltIn
if o.Anonymous.Allow { if o.Anonymous.Allow {
found := false found := false
for _, mode := range strings.Split(authorization.Mode, ",") { for _, mode := range strings.Split(authorization.Mode, ",") {
if mode == authorizer.ModeAlwaysAllow { if mode == authzmodes.ModeAlwaysAllow {
found = true found = true
break break
} }

View File

@ -24,10 +24,9 @@ import (
"k8s.io/kubernetes/pkg/controller/informers" "k8s.io/kubernetes/pkg/controller/informers"
"k8s.io/kubernetes/pkg/kubeapiserver/authorizer" "k8s.io/kubernetes/pkg/kubeapiserver/authorizer"
authzmodes "k8s.io/kubernetes/pkg/kubeapiserver/authorizer/modes"
) )
var AuthorizationModeChoices = []string{authorizer.ModeAlwaysAllow, authorizer.ModeAlwaysDeny, authorizer.ModeABAC, authorizer.ModeWebhook, authorizer.ModeRBAC}
type BuiltInAuthorizationOptions struct { type BuiltInAuthorizationOptions struct {
Mode string Mode string
PolicyFile string PolicyFile string
@ -38,7 +37,7 @@ type BuiltInAuthorizationOptions struct {
func NewBuiltInAuthorizationOptions() *BuiltInAuthorizationOptions { func NewBuiltInAuthorizationOptions() *BuiltInAuthorizationOptions {
return &BuiltInAuthorizationOptions{ return &BuiltInAuthorizationOptions{
Mode: authorizer.ModeAlwaysAllow, Mode: authzmodes.ModeAlwaysAllow,
WebhookCacheAuthorizedTTL: 5 * time.Minute, WebhookCacheAuthorizedTTL: 5 * time.Minute,
WebhookCacheUnauthorizedTTL: 30 * time.Second, WebhookCacheUnauthorizedTTL: 30 * time.Second,
} }
@ -52,7 +51,7 @@ func (s *BuiltInAuthorizationOptions) Validate() []error {
func (s *BuiltInAuthorizationOptions) AddFlags(fs *pflag.FlagSet) { func (s *BuiltInAuthorizationOptions) AddFlags(fs *pflag.FlagSet) {
fs.StringVar(&s.Mode, "authorization-mode", s.Mode, ""+ fs.StringVar(&s.Mode, "authorization-mode", s.Mode, ""+
"Ordered list of plug-ins to do authorization on secure port. Comma-delimited list of: "+ "Ordered list of plug-ins to do authorization on secure port. Comma-delimited list of: "+
strings.Join(AuthorizationModeChoices, ",")+".") strings.Join(authzmodes.AuthorizationModeChoices, ",")+".")
fs.StringVar(&s.PolicyFile, "authorization-policy-file", s.PolicyFile, ""+ 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.") "File with authorization policy in csv format, used with --authorization-mode=ABAC, on the secure port.")