Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow multiple providers for authorizationMode #42557

Merged
merged 1 commit into from
Apr 6, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion cmd/kubeadm/app/apis/kubeadm/fuzzer/fuzzer.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func KubeadmFuzzerFuncs(t apitesting.TestingCommon) []interface{} {
obj.API.AdvertiseAddress = "foo"
obj.Networking.ServiceSubnet = "foo"
obj.Networking.DNSDomain = "foo"
obj.AuthorizationMode = "foo"
obj.AuthorizationModes = []string{"foo"}
obj.CertificatesDir = "foo"
obj.APIServerCertSANs = []string{}
obj.Token = "foo"
Expand Down
12 changes: 6 additions & 6 deletions cmd/kubeadm/app/apis/kubeadm/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@ type EnvParams struct {
type MasterConfiguration struct {
metav1.TypeMeta

API API
Etcd Etcd
Networking Networking
KubernetesVersion string
CloudProvider string
AuthorizationMode string
API API
Etcd Etcd
Networking Networking
KubernetesVersion string
CloudProvider string
AuthorizationModes []string

Token string
TokenTTL time.Duration
Expand Down
4 changes: 2 additions & 2 deletions cmd/kubeadm/app/apis/kubeadm/v1alpha1/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ func SetDefaults_MasterConfiguration(obj *MasterConfiguration) {
obj.Networking.DNSDomain = DefaultServiceDNSDomain
}

if obj.AuthorizationMode == "" {
obj.AuthorizationMode = DefaultAuthorizationMode
if len(obj.AuthorizationModes) == 0 {
obj.AuthorizationModes = []string{DefaultAuthorizationMode}
}

if obj.CertificatesDir == "" {
Expand Down
12 changes: 6 additions & 6 deletions cmd/kubeadm/app/apis/kubeadm/v1alpha1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@ import (
type MasterConfiguration struct {
metav1.TypeMeta `json:",inline"`

API API `json:"api"`
Etcd Etcd `json:"etcd"`
Networking Networking `json:"networking"`
KubernetesVersion string `json:"kubernetesVersion"`
CloudProvider string `json:"cloudProvider"`
AuthorizationMode string `json:"authorizationMode"`
API API `json:"api"`
Etcd Etcd `json:"etcd"`
Networking Networking `json:"networking"`
KubernetesVersion string `json:"kubernetesVersion"`
CloudProvider string `json:"cloudProvider"`
AuthorizationModes []string `json:"authorizationModes"`

Token string `json:"token"`
TokenTTL time.Duration `json:"tokenTTL"`
Expand Down
22 changes: 17 additions & 5 deletions cmd/kubeadm/app/apis/kubeadm/validation/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ var cloudproviders = []string{
func ValidateMasterConfiguration(c *kubeadm.MasterConfiguration) field.ErrorList {
allErrs := field.ErrorList{}
allErrs = append(allErrs, ValidateCloudProvider(c.CloudProvider, field.NewPath("cloudprovider"))...)
allErrs = append(allErrs, ValidateAuthorizationMode(c.AuthorizationMode, field.NewPath("authorization-mode"))...)
allErrs = append(allErrs, ValidateAuthorizationModes(c.AuthorizationModes, field.NewPath("authorization-mode"))...)
allErrs = append(allErrs, ValidateNetworking(&c.Networking, field.NewPath("networking"))...)
allErrs = append(allErrs, ValidateAPIServerCertSANs(c.APIServerCertSANs, field.NewPath("cert-altnames"))...)
allErrs = append(allErrs, ValidateAbsolutePath(c.CertificatesDir, field.NewPath("certificates-dir"))...)
Expand All @@ -70,11 +70,23 @@ func ValidateNodeConfiguration(c *kubeadm.NodeConfiguration) field.ErrorList {
return allErrs
}

func ValidateAuthorizationMode(authzMode string, fldPath *field.Path) field.ErrorList {
if !authzmodes.IsValidAuthorizationMode(authzMode) {
return field.ErrorList{field.Invalid(fldPath, authzMode, "invalid authorization mode")}
func ValidateAuthorizationModes(authzModes []string, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
for _, authzMode := range authzModes {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should make sure here that you can't set it to RBAC,RBAC,ABAC,ABAC or the like. Duplicate values aren't allowed

if !authzmodes.IsValidAuthorizationMode(authzMode) {
allErrs = append(allErrs, field.Invalid(fldPath, authzMode, "invalid authorization mode"))
}
}

found := map[string]bool{}
for _, authzMode := range authzModes {
if found[authzMode] {
allErrs = append(allErrs, field.Invalid(fldPath, authzMode, "duplicate authorization mode"))
continue
}
found[authzMode] = true
}
return field.ErrorList{}
return allErrs
}

func ValidateDiscovery(c *kubeadm.NodeConfiguration, fldPath *field.Path) field.ErrorList {
Expand Down
25 changes: 14 additions & 11 deletions cmd/kubeadm/app/apis/kubeadm/validation/validation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,23 +45,26 @@ func TestValidateTokenDiscovery(t *testing.T) {
}
}

func TestValidateAuthorizationMode(t *testing.T) {
func TestValidateAuthorizationModes(t *testing.T) {
var tests = []struct {
s string
s []string
f *field.Path
expected bool
}{
{"", nil, false},
{"rBAC", nil, false}, // not supported
{"not valid", nil, false}, // not supported
{"RBAC", nil, true}, // supported
{"Webhook", nil, true}, // supported
{[]string{""}, nil, false},
{[]string{"rBAC"}, nil, false}, // not supported
{[]string{"rBAC", "Webhook"}, nil, false}, // not supported
{[]string{"RBAC", "Webhook", "Webhook"}, nil, false}, // not supported
{[]string{"not valid"}, nil, false}, // not supported
{[]string{"RBAC"}, nil, true}, // supported
{[]string{"Webhook"}, nil, true}, // supported
{[]string{"RBAC", "Webhook"}, nil, true}, // supported
}
for _, rt := range tests {
actual := ValidateAuthorizationMode(rt.s, rt.f)
actual := ValidateAuthorizationModes(rt.s, rt.f)
if (len(actual) == 0) != rt.expected {
t.Errorf(
"failed ValidateAuthorizationMode:\n\texpected: %t\n\t actual: %t",
"failed ValidateAuthorizationModes:\n\texpected: %t\n\t actual: %t",
rt.expected,
(len(actual) == 0),
)
Expand Down Expand Up @@ -172,15 +175,15 @@ func TestValidateMasterConfiguration(t *testing.T) {
}{
{&kubeadm.MasterConfiguration{}, false},
{&kubeadm.MasterConfiguration{
AuthorizationMode: "RBAC",
AuthorizationModes: []string{"RBAC"},
Networking: kubeadm.Networking{
ServiceSubnet: "10.96.0.1/12",
DNSDomain: "cluster.local",
},
CertificatesDir: "/some/cert/dir",
}, false},
{&kubeadm.MasterConfiguration{
AuthorizationMode: "RBAC",
AuthorizationModes: []string{"RBAC"},
Networking: kubeadm.Networking{
ServiceSubnet: "10.96.0.1/12",
DNSDomain: "cluster.local",
Expand Down
2 changes: 1 addition & 1 deletion cmd/kubeadm/app/cmd/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ func setInitDynamicDefaults(cfg *kubeadmapi.MasterConfiguration) error {
}

fmt.Printf("[init] Using Kubernetes version: %s\n", cfg.KubernetesVersion)
fmt.Printf("[init] Using Authorization mode: %s\n", cfg.AuthorizationMode)
fmt.Printf("[init] Using Authorization mode: %v\n", cfg.AuthorizationModes)

// Warn about the limitations with the current cloudprovider solution.
if cfg.CloudProvider != "" {
Expand Down
23 changes: 12 additions & 11 deletions cmd/kubeadm/app/master/manifests.go
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ func getAPIServerCommand(cfg *kubeadmapi.MasterConfiguration, selfHosted bool) [

command = getComponentBaseCommand(apiServer)
command = append(command, getExtraParameters(cfg.APIServerExtraArgs, defaultArguments)...)
command = append(command, getAuthzParameters(cfg.AuthorizationMode)...)
command = append(command, getAuthzParameters(cfg.AuthorizationModes)...)

if selfHosted {
command = append(command, "--advertise-address=$(POD_IP)")
Expand Down Expand Up @@ -457,22 +457,23 @@ func getSelfHostedAPIServerEnv() []api.EnvVar {
return append(getProxyEnvVars(), podIPEnvVar)
}

func getAuthzParameters(authzMode string) []string {
func getAuthzParameters(modes []string) []string {
command := []string{}
// RBAC is always on. If the user specified
authzModes := []string{authzmodes.ModeRBAC}
if len(authzMode) != 0 && authzMode != authzmodes.ModeRBAC {
authzModes = append(authzModes, authzMode)
for _, authzMode := range modes {
if len(authzMode) != 0 && authzMode != authzmodes.ModeRBAC {
authzModes = append(authzModes, authzMode)
}
switch authzMode {
case authzmodes.ModeABAC:
command = append(command, "--authorization-policy-file="+kubeadmconstants.AuthorizationPolicyPath)
case authzmodes.ModeWebhook:
command = append(command, "--authorization-webhook-config-file="+kubeadmconstants.AuthorizationWebhookConfigPath)
}
}

command = append(command, "--authorization-mode="+strings.Join(authzModes, ","))

switch authzMode {
case authzmodes.ModeABAC:
command = append(command, "--authorization-policy-file="+kubeadmconstants.AuthorizationPolicyPath)
case authzmodes.ModeWebhook:
command = append(command, "--authorization-webhook-config-file="+kubeadmconstants.AuthorizationWebhookConfigPath)
}
return command
}

Expand Down
37 changes: 21 additions & 16 deletions cmd/kubeadm/app/master/manifests_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -595,59 +595,64 @@ func TestGetSchedulerCommand(t *testing.T) {

func TestGetAuthzParameters(t *testing.T) {
var tests = []struct {
authMode string
authMode []string
expected []string
}{
{
authMode: "",
authMode: []string{},
expected: []string{
"--authorization-mode=RBAC",
},
},
{
authMode: "RBAC",
authMode: []string{"RBAC"},
expected: []string{
"--authorization-mode=RBAC",
},
},
{
authMode: "AlwaysAllow",
authMode: []string{"AlwaysAllow"},
expected: []string{
"--authorization-mode=RBAC,AlwaysAllow",
},
},
{
authMode: "AlwaysDeny",
authMode: []string{"AlwaysDeny"},
expected: []string{
"--authorization-mode=RBAC,AlwaysDeny",
},
},
{
authMode: "ABAC",
authMode: []string{"ABAC"},
expected: []string{
"--authorization-mode=RBAC,ABAC",
"--authorization-policy-file=/etc/kubernetes/abac_policy.json",
},
},
{
authMode: "Webhook",
authMode: []string{"ABAC", "Webhook"},
expected: []string{
"--authorization-mode=RBAC,Webhook",
"--authorization-mode=RBAC,ABAC,Webhook",
"--authorization-policy-file=/etc/kubernetes/abac_policy.json",
"--authorization-webhook-config-file=/etc/kubernetes/webhook_authz.conf",
},
},
{
authMode: []string{"ABAC", "RBAC", "Webhook"},
expected: []string{
"--authorization-mode=RBAC,ABAC,Webhook",
"--authorization-policy-file=/etc/kubernetes/abac_policy.json",
"--authorization-webhook-config-file=/etc/kubernetes/webhook_authz.conf",
},
},
}

for _, rt := range tests {
actual := getAuthzParameters(rt.authMode)
for i := range actual {
if actual[i] != rt.expected[i] {
t.Errorf(
"failed getAuthzParameters:\n\texpected: %s\n\t actual: %s",
rt.expected[i],
actual[i],
)
}
sort.Strings(actual)
sort.Strings(rt.expected)
if !reflect.DeepEqual(actual, rt.expected) {
t.Errorf("failed getAuthzParameters:\nexpected:\n%v\nsaw:\n%v", rt.expected, actual)
}
}
}
Expand Down
12 changes: 7 additions & 5 deletions cmd/kubeadm/app/preflight/checks.go
Original file line number Diff line number Diff line change
Expand Up @@ -520,11 +520,13 @@ func RunInitMasterChecks(cfg *kubeadmapi.MasterConfiguration) error {
}

// Check the config for authorization mode
switch cfg.AuthorizationMode {
case authzmodes.ModeABAC:
checks = append(checks, FileExistingCheck{Path: kubeadmconstants.AuthorizationPolicyPath})
case authzmodes.ModeWebhook:
checks = append(checks, FileExistingCheck{Path: kubeadmconstants.AuthorizationWebhookConfigPath})
for _, authzMode := range cfg.AuthorizationModes {
switch authzMode {
case authzmodes.ModeABAC:
checks = append(checks, FileExistingCheck{Path: kubeadmconstants.AuthorizationPolicyPath})
case authzmodes.ModeWebhook:
checks = append(checks, FileExistingCheck{Path: kubeadmconstants.AuthorizationWebhookConfigPath})
}
}

return RunChecks(checks, os.Stderr)
Expand Down