mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-06 02:34:03 +00:00
Merge pull request #42557 from xilabao/use-authorizationModes
Automatic merge from submit-queue Allow multiple providers for authorizationMode fixes https://github.com/kubernetes/kubeadm/issues/177
This commit is contained in:
commit
2d66f7bd28
@ -32,7 +32,7 @@ func KubeadmFuzzerFuncs(t apitesting.TestingCommon) []interface{} {
|
|||||||
obj.API.AdvertiseAddress = "foo"
|
obj.API.AdvertiseAddress = "foo"
|
||||||
obj.Networking.ServiceSubnet = "foo"
|
obj.Networking.ServiceSubnet = "foo"
|
||||||
obj.Networking.DNSDomain = "foo"
|
obj.Networking.DNSDomain = "foo"
|
||||||
obj.AuthorizationMode = "foo"
|
obj.AuthorizationModes = []string{"foo"}
|
||||||
obj.CertificatesDir = "foo"
|
obj.CertificatesDir = "foo"
|
||||||
obj.APIServerCertSANs = []string{}
|
obj.APIServerCertSANs = []string{}
|
||||||
obj.Token = "foo"
|
obj.Token = "foo"
|
||||||
|
@ -33,12 +33,12 @@ type EnvParams struct {
|
|||||||
type MasterConfiguration struct {
|
type MasterConfiguration struct {
|
||||||
metav1.TypeMeta
|
metav1.TypeMeta
|
||||||
|
|
||||||
API API
|
API API
|
||||||
Etcd Etcd
|
Etcd Etcd
|
||||||
Networking Networking
|
Networking Networking
|
||||||
KubernetesVersion string
|
KubernetesVersion string
|
||||||
CloudProvider string
|
CloudProvider string
|
||||||
AuthorizationMode string
|
AuthorizationModes []string
|
||||||
|
|
||||||
Token string
|
Token string
|
||||||
TokenTTL time.Duration
|
TokenTTL time.Duration
|
||||||
|
@ -59,8 +59,8 @@ func SetDefaults_MasterConfiguration(obj *MasterConfiguration) {
|
|||||||
obj.Networking.DNSDomain = DefaultServiceDNSDomain
|
obj.Networking.DNSDomain = DefaultServiceDNSDomain
|
||||||
}
|
}
|
||||||
|
|
||||||
if obj.AuthorizationMode == "" {
|
if len(obj.AuthorizationModes) == 0 {
|
||||||
obj.AuthorizationMode = DefaultAuthorizationMode
|
obj.AuthorizationModes = []string{DefaultAuthorizationMode}
|
||||||
}
|
}
|
||||||
|
|
||||||
if obj.CertificatesDir == "" {
|
if obj.CertificatesDir == "" {
|
||||||
|
@ -25,12 +25,12 @@ import (
|
|||||||
type MasterConfiguration struct {
|
type MasterConfiguration struct {
|
||||||
metav1.TypeMeta `json:",inline"`
|
metav1.TypeMeta `json:",inline"`
|
||||||
|
|
||||||
API API `json:"api"`
|
API API `json:"api"`
|
||||||
Etcd Etcd `json:"etcd"`
|
Etcd Etcd `json:"etcd"`
|
||||||
Networking Networking `json:"networking"`
|
Networking Networking `json:"networking"`
|
||||||
KubernetesVersion string `json:"kubernetesVersion"`
|
KubernetesVersion string `json:"kubernetesVersion"`
|
||||||
CloudProvider string `json:"cloudProvider"`
|
CloudProvider string `json:"cloudProvider"`
|
||||||
AuthorizationMode string `json:"authorizationMode"`
|
AuthorizationModes []string `json:"authorizationModes"`
|
||||||
|
|
||||||
Token string `json:"token"`
|
Token string `json:"token"`
|
||||||
TokenTTL time.Duration `json:"tokenTTL"`
|
TokenTTL time.Duration `json:"tokenTTL"`
|
||||||
|
@ -52,7 +52,7 @@ var cloudproviders = []string{
|
|||||||
func ValidateMasterConfiguration(c *kubeadm.MasterConfiguration) field.ErrorList {
|
func ValidateMasterConfiguration(c *kubeadm.MasterConfiguration) field.ErrorList {
|
||||||
allErrs := field.ErrorList{}
|
allErrs := field.ErrorList{}
|
||||||
allErrs = append(allErrs, ValidateCloudProvider(c.CloudProvider, field.NewPath("cloudprovider"))...)
|
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, ValidateNetworking(&c.Networking, field.NewPath("networking"))...)
|
||||||
allErrs = append(allErrs, ValidateAPIServerCertSANs(c.APIServerCertSANs, field.NewPath("cert-altnames"))...)
|
allErrs = append(allErrs, ValidateAPIServerCertSANs(c.APIServerCertSANs, field.NewPath("cert-altnames"))...)
|
||||||
allErrs = append(allErrs, ValidateAbsolutePath(c.CertificatesDir, field.NewPath("certificates-dir"))...)
|
allErrs = append(allErrs, ValidateAbsolutePath(c.CertificatesDir, field.NewPath("certificates-dir"))...)
|
||||||
@ -70,11 +70,23 @@ func ValidateNodeConfiguration(c *kubeadm.NodeConfiguration) field.ErrorList {
|
|||||||
return allErrs
|
return allErrs
|
||||||
}
|
}
|
||||||
|
|
||||||
func ValidateAuthorizationMode(authzMode string, fldPath *field.Path) field.ErrorList {
|
func ValidateAuthorizationModes(authzModes []string, fldPath *field.Path) field.ErrorList {
|
||||||
if !authzmodes.IsValidAuthorizationMode(authzMode) {
|
allErrs := field.ErrorList{}
|
||||||
return field.ErrorList{field.Invalid(fldPath, authzMode, "invalid authorization mode")}
|
for _, authzMode := range authzModes {
|
||||||
|
if !authzmodes.IsValidAuthorizationMode(authzMode) {
|
||||||
|
allErrs = append(allErrs, field.Invalid(fldPath, authzMode, "invalid authorization mode"))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return field.ErrorList{}
|
|
||||||
|
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 allErrs
|
||||||
}
|
}
|
||||||
|
|
||||||
func ValidateDiscovery(c *kubeadm.NodeConfiguration, fldPath *field.Path) field.ErrorList {
|
func ValidateDiscovery(c *kubeadm.NodeConfiguration, fldPath *field.Path) field.ErrorList {
|
||||||
|
@ -45,23 +45,26 @@ func TestValidateTokenDiscovery(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestValidateAuthorizationMode(t *testing.T) {
|
func TestValidateAuthorizationModes(t *testing.T) {
|
||||||
var tests = []struct {
|
var tests = []struct {
|
||||||
s string
|
s []string
|
||||||
f *field.Path
|
f *field.Path
|
||||||
expected bool
|
expected bool
|
||||||
}{
|
}{
|
||||||
{"", nil, false},
|
{[]string{""}, nil, false},
|
||||||
{"rBAC", nil, false}, // not supported
|
{[]string{"rBAC"}, nil, false}, // not supported
|
||||||
{"not valid", nil, false}, // not supported
|
{[]string{"rBAC", "Webhook"}, nil, false}, // not supported
|
||||||
{"RBAC", nil, true}, // supported
|
{[]string{"RBAC", "Webhook", "Webhook"}, nil, false}, // not supported
|
||||||
{"Webhook", nil, true}, // 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 {
|
for _, rt := range tests {
|
||||||
actual := ValidateAuthorizationMode(rt.s, rt.f)
|
actual := ValidateAuthorizationModes(rt.s, rt.f)
|
||||||
if (len(actual) == 0) != rt.expected {
|
if (len(actual) == 0) != rt.expected {
|
||||||
t.Errorf(
|
t.Errorf(
|
||||||
"failed ValidateAuthorizationMode:\n\texpected: %t\n\t actual: %t",
|
"failed ValidateAuthorizationModes:\n\texpected: %t\n\t actual: %t",
|
||||||
rt.expected,
|
rt.expected,
|
||||||
(len(actual) == 0),
|
(len(actual) == 0),
|
||||||
)
|
)
|
||||||
@ -172,7 +175,7 @@ func TestValidateMasterConfiguration(t *testing.T) {
|
|||||||
}{
|
}{
|
||||||
{&kubeadm.MasterConfiguration{}, false},
|
{&kubeadm.MasterConfiguration{}, false},
|
||||||
{&kubeadm.MasterConfiguration{
|
{&kubeadm.MasterConfiguration{
|
||||||
AuthorizationMode: "RBAC",
|
AuthorizationModes: []string{"RBAC"},
|
||||||
Networking: kubeadm.Networking{
|
Networking: kubeadm.Networking{
|
||||||
ServiceSubnet: "10.96.0.1/12",
|
ServiceSubnet: "10.96.0.1/12",
|
||||||
DNSDomain: "cluster.local",
|
DNSDomain: "cluster.local",
|
||||||
@ -180,7 +183,7 @@ func TestValidateMasterConfiguration(t *testing.T) {
|
|||||||
CertificatesDir: "/some/cert/dir",
|
CertificatesDir: "/some/cert/dir",
|
||||||
}, false},
|
}, false},
|
||||||
{&kubeadm.MasterConfiguration{
|
{&kubeadm.MasterConfiguration{
|
||||||
AuthorizationMode: "RBAC",
|
AuthorizationModes: []string{"RBAC"},
|
||||||
Networking: kubeadm.Networking{
|
Networking: kubeadm.Networking{
|
||||||
ServiceSubnet: "10.96.0.1/12",
|
ServiceSubnet: "10.96.0.1/12",
|
||||||
DNSDomain: "cluster.local",
|
DNSDomain: "cluster.local",
|
||||||
|
@ -58,7 +58,7 @@ func setInitDynamicDefaults(cfg *kubeadmapi.MasterConfiguration) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("[init] Using Kubernetes version: %s\n", cfg.KubernetesVersion)
|
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.
|
// Warn about the limitations with the current cloudprovider solution.
|
||||||
if cfg.CloudProvider != "" {
|
if cfg.CloudProvider != "" {
|
||||||
|
@ -330,7 +330,7 @@ func getAPIServerCommand(cfg *kubeadmapi.MasterConfiguration, selfHosted bool) [
|
|||||||
|
|
||||||
command = getComponentBaseCommand(apiServer)
|
command = getComponentBaseCommand(apiServer)
|
||||||
command = append(command, getExtraParameters(cfg.APIServerExtraArgs, defaultArguments)...)
|
command = append(command, getExtraParameters(cfg.APIServerExtraArgs, defaultArguments)...)
|
||||||
command = append(command, getAuthzParameters(cfg.AuthorizationMode)...)
|
command = append(command, getAuthzParameters(cfg.AuthorizationModes)...)
|
||||||
|
|
||||||
if selfHosted {
|
if selfHosted {
|
||||||
command = append(command, "--advertise-address=$(POD_IP)")
|
command = append(command, "--advertise-address=$(POD_IP)")
|
||||||
@ -460,22 +460,23 @@ func getSelfHostedAPIServerEnv() []api.EnvVar {
|
|||||||
return append(getProxyEnvVars(), podIPEnvVar)
|
return append(getProxyEnvVars(), podIPEnvVar)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getAuthzParameters(authzMode string) []string {
|
func getAuthzParameters(modes []string) []string {
|
||||||
command := []string{}
|
command := []string{}
|
||||||
// RBAC is always on. If the user specified
|
// RBAC is always on. If the user specified
|
||||||
authzModes := []string{authzmodes.ModeRBAC}
|
authzModes := []string{authzmodes.ModeRBAC}
|
||||||
if len(authzMode) != 0 && authzMode != authzmodes.ModeRBAC {
|
for _, authzMode := range modes {
|
||||||
authzModes = append(authzModes, authzMode)
|
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, ","))
|
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
|
return command
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -652,44 +652,53 @@ func TestGetSchedulerCommand(t *testing.T) {
|
|||||||
|
|
||||||
func TestGetAuthzParameters(t *testing.T) {
|
func TestGetAuthzParameters(t *testing.T) {
|
||||||
var tests = []struct {
|
var tests = []struct {
|
||||||
authMode string
|
authMode []string
|
||||||
expected []string
|
expected []string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
authMode: "",
|
authMode: []string{},
|
||||||
expected: []string{
|
expected: []string{
|
||||||
"--authorization-mode=RBAC",
|
"--authorization-mode=RBAC",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
authMode: "RBAC",
|
authMode: []string{"RBAC"},
|
||||||
expected: []string{
|
expected: []string{
|
||||||
"--authorization-mode=RBAC",
|
"--authorization-mode=RBAC",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
authMode: "AlwaysAllow",
|
authMode: []string{"AlwaysAllow"},
|
||||||
expected: []string{
|
expected: []string{
|
||||||
"--authorization-mode=RBAC,AlwaysAllow",
|
"--authorization-mode=RBAC,AlwaysAllow",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
authMode: "AlwaysDeny",
|
authMode: []string{"AlwaysDeny"},
|
||||||
expected: []string{
|
expected: []string{
|
||||||
"--authorization-mode=RBAC,AlwaysDeny",
|
"--authorization-mode=RBAC,AlwaysDeny",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
authMode: "ABAC",
|
authMode: []string{"ABAC"},
|
||||||
expected: []string{
|
expected: []string{
|
||||||
"--authorization-mode=RBAC,ABAC",
|
"--authorization-mode=RBAC,ABAC",
|
||||||
"--authorization-policy-file=/etc/kubernetes/abac_policy.json",
|
"--authorization-policy-file=/etc/kubernetes/abac_policy.json",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
authMode: "Webhook",
|
authMode: []string{"ABAC", "Webhook"},
|
||||||
expected: []string{
|
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",
|
"--authorization-webhook-config-file=/etc/kubernetes/webhook_authz.conf",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -697,14 +706,10 @@ func TestGetAuthzParameters(t *testing.T) {
|
|||||||
|
|
||||||
for _, rt := range tests {
|
for _, rt := range tests {
|
||||||
actual := getAuthzParameters(rt.authMode)
|
actual := getAuthzParameters(rt.authMode)
|
||||||
for i := range actual {
|
sort.Strings(actual)
|
||||||
if actual[i] != rt.expected[i] {
|
sort.Strings(rt.expected)
|
||||||
t.Errorf(
|
if !reflect.DeepEqual(actual, rt.expected) {
|
||||||
"failed getAuthzParameters:\n\texpected: %s\n\t actual: %s",
|
t.Errorf("failed getAuthzParameters:\nexpected:\n%v\nsaw:\n%v", rt.expected, actual)
|
||||||
rt.expected[i],
|
|
||||||
actual[i],
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -525,11 +525,13 @@ func RunInitMasterChecks(cfg *kubeadmapi.MasterConfiguration) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check the config for authorization mode
|
// Check the config for authorization mode
|
||||||
switch cfg.AuthorizationMode {
|
for _, authzMode := range cfg.AuthorizationModes {
|
||||||
case authzmodes.ModeABAC:
|
switch authzMode {
|
||||||
checks = append(checks, FileExistingCheck{Path: kubeadmconstants.AuthorizationPolicyPath})
|
case authzmodes.ModeABAC:
|
||||||
case authzmodes.ModeWebhook:
|
checks = append(checks, FileExistingCheck{Path: kubeadmconstants.AuthorizationPolicyPath})
|
||||||
checks = append(checks, FileExistingCheck{Path: kubeadmconstants.AuthorizationWebhookConfigPath})
|
case authzmodes.ModeWebhook:
|
||||||
|
checks = append(checks, FileExistingCheck{Path: kubeadmconstants.AuthorizationWebhookConfigPath})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return RunChecks(checks, os.Stderr)
|
return RunChecks(checks, os.Stderr)
|
||||||
|
Loading…
Reference in New Issue
Block a user