[client-go] [cli-runtime] [133916]: handle properly config override logic when override provides ClientKey, ClientCertificate

Signed-off-by: Nikita B <n2h9z4@gmail.com>

Kubernetes-commit: fc8907da38dc1a6af7d7b2c18d87c1dd35ca8c68
This commit is contained in:
Nikita B
2025-09-06 14:05:59 +02:00
committed by Kubernetes Publisher
parent 14aa03798d
commit e703bc019f
2 changed files with 86 additions and 0 deletions

View File

@@ -533,6 +533,19 @@ func (config *DirectClientConfig) getAuthInfo() (clientcmdapi.AuthInfo, error) {
if err := merge(mergedAuthInfo, &config.overrides.AuthInfo); err != nil {
return clientcmdapi.AuthInfo{}, err
}
// Handle ClientKey/ClientKeyData conflict: if override sets ClientKey, also use override's ClientKeyData
// otherwise if original config has ClientKeyData set,
// validation returns error "client-key-data and client-key are both specified <user-name>"
if len(config.overrides.AuthInfo.ClientKey) > 0 {
mergedAuthInfo.ClientKeyData = config.overrides.AuthInfo.ClientKeyData
}
// Handle ClientCertificate/ClientCertificateData conflict, if override sets ClientCertificate, also use override's ClientCertificateData
// otherwise if original config has ClientCertificateData set,
// validation returns error "client-cert-data and client-cert are both specified <user-name>"
if len(config.overrides.AuthInfo.ClientCertificate) > 0 {
mergedAuthInfo.ClientCertificateData = config.overrides.AuthInfo.ClientCertificateData
}
}
return *mergedAuthInfo, nil

View File

@@ -1222,3 +1222,76 @@ func TestMergeRawConfigDoOverride(t *testing.T) {
t.Errorf("Expected namespace %v, got %v", config.Contexts["clean"].Namespace, act.Contexts["clean"].Namespace)
}
}
func TestClientCertOverrideData(t *testing.T) {
// Test that when overrides contain cert/key file paths, the corresponding
// data fields are properly handled to avoid validation conflicts
// in particular code in DirectClientConfig::getAuthInfo
certFile, err := os.CreateTemp("", "test-client-*.crt")
if err != nil {
t.Fatalf("Failed to create temp cert file: %v", err)
}
defer utiltesting.CloseAndRemove(t, certFile)
keyFile, err := os.CreateTemp("", "test-client-*.key")
if err != nil {
t.Fatalf("Failed to create temp key file: %v", err)
}
defer utiltesting.CloseAndRemove(t, keyFile)
if err := os.WriteFile(certFile.Name(), []byte("dummy-cert-content"), 0600); err != nil {
t.Fatalf("Failed to write cert file: %v", err)
}
if err := os.WriteFile(keyFile.Name(), []byte("dummy-key-content"), 0600); err != nil {
t.Fatalf("Failed to write key file: %v", err)
}
baseConfig := clientcmdapi.Config{
Clusters: map[string]*clientcmdapi.Cluster{
"test-cluster": {
Server: "https://example.com:6443",
CertificateAuthorityData: []byte("fake-ca-data"),
},
},
AuthInfos: map[string]*clientcmdapi.AuthInfo{
"test-user": {
ClientCertificateData: []byte("base-cert-data"),
ClientKeyData: []byte("base-key-data"),
},
},
Contexts: map[string]*clientcmdapi.Context{
"test-context": {
Cluster: "test-cluster",
AuthInfo: "test-user",
},
},
CurrentContext: "test-context",
}
overrides := &ConfigOverrides{
AuthInfo: clientcmdapi.AuthInfo{
ClientCertificate: certFile.Name(),
ClientCertificateData: nil,
ClientKey: keyFile.Name(),
ClientKeyData: nil,
},
}
clientConfig := NewNonInteractiveClientConfig(baseConfig, "test-context", overrides, nil)
mergedConfig, err := clientConfig.MergedRawConfig()
if err != nil {
t.Fatalf("MergedRawConfig() failed: %v", err)
}
authInfo := mergedConfig.AuthInfos["test-user"]
if authInfo == nil {
t.Fatalf("Expected AuthInfo 'test-user' not found")
}
matchStringArg(certFile.Name(), authInfo.ClientCertificate, t)
matchStringArg(keyFile.Name(), authInfo.ClientKey, t)
matchByteArg(nil, authInfo.ClientCertificateData, t)
matchByteArg(nil, authInfo.ClientKeyData, t)
}