diff --git a/tools/clientcmd/api/types.go b/tools/clientcmd/api/types.go index 1f1209f8..44317dd0 100644 --- a/tools/clientcmd/api/types.go +++ b/tools/clientcmd/api/types.go @@ -70,6 +70,9 @@ type Cluster struct { LocationOfOrigin string // Server is the address of the kubernetes cluster (https://hostname:port). Server string `json:"server"` + // TLSServerName is used to check server certificate. If TLSServerName is empty, the hostname used to contact the server is used. + // +optional + TLSServerName string `json:"tls-server-name,omitempty"` // InsecureSkipTLSVerify skips the validity check for the server's certificate. This will make your HTTPS connections insecure. // +optional InsecureSkipTLSVerify bool `json:"insecure-skip-tls-verify,omitempty"` diff --git a/tools/clientcmd/api/v1/types.go b/tools/clientcmd/api/v1/types.go index 2159ffc7..8ccacd3f 100644 --- a/tools/clientcmd/api/v1/types.go +++ b/tools/clientcmd/api/v1/types.go @@ -63,6 +63,9 @@ type Preferences struct { type Cluster struct { // Server is the address of the kubernetes cluster (https://hostname:port). Server string `json:"server"` + // TLSServerName is used to check server certificate. If TLSServerName is empty, the hostname used to contact the server is used. + // +optional + TLSServerName string `json:"tls-server-name,omitempty"` // InsecureSkipTLSVerify skips the validity check for the server's certificate. This will make your HTTPS connections insecure. // +optional InsecureSkipTLSVerify bool `json:"insecure-skip-tls-verify,omitempty"` diff --git a/tools/clientcmd/client_config.go b/tools/clientcmd/client_config.go index 44115130..6b5f3f73 100644 --- a/tools/clientcmd/client_config.go +++ b/tools/clientcmd/client_config.go @@ -210,6 +210,7 @@ func getServerIdentificationPartialConfig(configAuthInfo clientcmdapi.AuthInfo, configClientConfig.CAFile = configClusterInfo.CertificateAuthority configClientConfig.CAData = configClusterInfo.CertificateAuthorityData configClientConfig.Insecure = configClusterInfo.InsecureSkipTLSVerify + configClientConfig.ServerName = configClusterInfo.TLSServerName mergo.MergeWithOverwrite(mergedConfig, configClientConfig) return mergedConfig, nil @@ -460,6 +461,10 @@ func (config *DirectClientConfig) getCluster() (clientcmdapi.Cluster, error) { mergedClusterInfo.CertificateAuthorityData = config.overrides.ClusterInfo.CertificateAuthorityData } + if config.overrides.ClusterInfo.TLSServerName != "" { + mergedClusterInfo.TLSServerName = config.overrides.ClusterInfo.TLSServerName + } + return *mergedClusterInfo, nil } diff --git a/tools/clientcmd/client_config_test.go b/tools/clientcmd/client_config_test.go index aae65f85..e89ce147 100644 --- a/tools/clientcmd/client_config_test.go +++ b/tools/clientcmd/client_config_test.go @@ -180,6 +180,25 @@ func TestCAOverridesCAData(t *testing.T) { matchByteArg(nil, actualCfg.TLSClientConfig.CAData, t) } +func TestTLSServerName(t *testing.T) { + config := createValidTestConfig() + + clientBuilder := NewNonInteractiveClientConfig(*config, "clean", &ConfigOverrides{ + ClusterInfo: clientcmdapi.Cluster{ + TLSServerName: "overridden-server-name", + }, + }, nil) + + actualCfg, err := clientBuilder.ClientConfig() + if err != nil { + t.Errorf("Unexpected error: %v", err) + } + + matchStringArg("overridden-server-name", actualCfg.ServerName, t) + matchStringArg("", actualCfg.TLSClientConfig.CAFile, t) + matchByteArg(nil, actualCfg.TLSClientConfig.CAData, t) +} + func TestMergeContext(t *testing.T) { const namespace = "overridden-namespace" @@ -411,6 +430,7 @@ func TestCreateClean(t *testing.T) { matchStringArg("", clientConfig.APIPath, t) matchBoolArg(config.Clusters["clean"].InsecureSkipTLSVerify, clientConfig.Insecure, t) matchStringArg(config.AuthInfos["clean"].Token, clientConfig.BearerToken, t) + matchStringArg(config.Clusters["clean"].TLSServerName, clientConfig.ServerName, t) } func TestCreateCleanWithPrefix(t *testing.T) { @@ -461,6 +481,7 @@ func TestCreateCleanDefault(t *testing.T) { } matchStringArg(config.Clusters["clean"].Server, clientConfig.Host, t) + matchStringArg(config.Clusters["clean"].TLSServerName, clientConfig.ServerName, t) matchBoolArg(config.Clusters["clean"].InsecureSkipTLSVerify, clientConfig.Insecure, t) matchStringArg(config.AuthInfos["clean"].Token, clientConfig.BearerToken, t) } @@ -477,6 +498,7 @@ func TestCreateCleanDefaultCluster(t *testing.T) { } matchStringArg(config.Clusters["clean"].Server, clientConfig.Host, t) + matchStringArg(config.Clusters["clean"].TLSServerName, clientConfig.ServerName, t) matchBoolArg(config.Clusters["clean"].InsecureSkipTLSVerify, clientConfig.Insecure, t) matchStringArg(config.AuthInfos["clean"].Token, clientConfig.BearerToken, t) } diff --git a/tools/clientcmd/overrides.go b/tools/clientcmd/overrides.go index bfca0328..95cba0fa 100644 --- a/tools/clientcmd/overrides.go +++ b/tools/clientcmd/overrides.go @@ -71,6 +71,7 @@ type ClusterOverrideFlags struct { APIVersion FlagInfo CertificateAuthority FlagInfo InsecureSkipTLSVerify FlagInfo + TLSServerName FlagInfo } // FlagInfo contains information about how to register a flag. This struct is useful if you want to provide a way for an extender to @@ -145,6 +146,7 @@ const ( FlagContext = "context" FlagNamespace = "namespace" FlagAPIServer = "server" + FlagTLSServerName = "tls-server-name" FlagInsecure = "insecure-skip-tls-verify" FlagCertFile = "client-certificate" FlagKeyFile = "client-key" @@ -189,6 +191,7 @@ func RecommendedClusterOverrideFlags(prefix string) ClusterOverrideFlags { APIServer: FlagInfo{prefix + FlagAPIServer, "", "", "The address and port of the Kubernetes API server"}, CertificateAuthority: FlagInfo{prefix + FlagCAFile, "", "", "Path to a cert file for the certificate authority"}, InsecureSkipTLSVerify: FlagInfo{prefix + FlagInsecure, "", "false", "If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure"}, + TLSServerName: FlagInfo{prefix + FlagTLSServerName, "", "", "If provided, this name will be used to validate server certificate. If this is not provided, hostname used to contact the server is used."}, } } @@ -226,6 +229,7 @@ func BindClusterFlags(clusterInfo *clientcmdapi.Cluster, flags *pflag.FlagSet, f flagNames.APIServer.BindStringFlag(flags, &clusterInfo.Server) flagNames.CertificateAuthority.BindStringFlag(flags, &clusterInfo.CertificateAuthority) flagNames.InsecureSkipTLSVerify.BindBoolFlag(flags, &clusterInfo.InsecureSkipTLSVerify) + flagNames.TLSServerName.BindStringFlag(flags, &clusterInfo.TLSServerName) } // BindFlags is a convenience method to bind the specified flags to their associated variables