Feat: support token retrieval via AuthInfo.Exec command (#6721)

Signed-off-by: co_gwre <co@guidewire.com>
Co-authored-by: co_gwre <co@guidewire.com>
This commit is contained in:
Chaitanyareddy0702
2025-03-13 07:44:18 +05:30
committed by GitHub
parent c48ded1994
commit d9fcebb9e8

View File

@@ -19,7 +19,10 @@ package multicluster
import (
"bytes"
"context"
"encoding/json"
"fmt"
"os"
"os/exec"
"strings"
"time"
@@ -125,10 +128,20 @@ func (clusterConfig *KubeClusterConfig) createOrUpdateClusterSecret(ctx context.
data["ca.crt"] = clusterConfig.Cluster.CertificateAuthorityData
}
}
if len(clusterConfig.AuthInfo.Token) > 0 {
switch {
case len(clusterConfig.AuthInfo.Token) > 0:
credentialType = clusterv1alpha1.CredentialTypeServiceAccountToken
data["token"] = []byte(clusterConfig.AuthInfo.Token)
} else {
case clusterConfig.AuthInfo.Exec != nil:
token, err := getTokenFromExec(clusterConfig.AuthInfo.Exec)
if err != nil {
return err
}
credentialType = clusterv1alpha1.CredentialTypeServiceAccountToken
data["token"] = []byte(token)
default:
credentialType = clusterv1alpha1.CredentialTypeX509Certificate
data["tls.crt"] = clusterConfig.AuthInfo.ClientCertificateData
data["tls.key"] = clusterConfig.AuthInfo.ClientKeyData
@@ -598,3 +611,54 @@ func getMutableClusterSecret(ctx context.Context, c client.Client, clusterName s
}
return clusterSecret, nil
}
func getTokenFromExec(execConfig *clientcmdapi.ExecConfig) (string, error) {
// #nosec G204 -- This is intentionally running an exec command with user-provided input
// The execConfig comes from the kubeconfig which should be trusted in this context
cmdPath := execConfig.Command
if strings.Contains(cmdPath, "..") {
return "", fmt.Errorf("command path must not contain '..'")
}
if strings.ContainsAny(cmdPath, "$;&|<>\"'\\") {
return "", fmt.Errorf("command must not contain shell metacharacters")
}
for _, arg := range execConfig.Args {
if strings.ContainsAny(arg, "$;&|<>\\") {
return "", fmt.Errorf("arguments must not contain shell metacharacters")
}
}
cmd := exec.Command(cmdPath, execConfig.Args...) // #nosec G204
env := os.Environ()
for _, e := range execConfig.Env {
if strings.ContainsAny(e.Name, "=$;\n") || strings.ContainsAny(e.Value, "\n") {
return "", fmt.Errorf("environment variable names and values must not contain control characters")
}
env = append(env, fmt.Sprintf("%s=%s", e.Name, e.Value))
}
cmd.Env = env
output, err := cmd.CombinedOutput()
if err != nil {
return "", fmt.Errorf("failed to execute auth command: %w", err)
}
var execCredential struct {
Status struct {
Token string `json:"token"`
} `json:"status"`
}
if err := json.Unmarshal(output, &execCredential); err != nil {
return "", fmt.Errorf("failed to parse exec command output: %w", err)
}
if execCredential.Status.Token == "" {
return "", fmt.Errorf("token not found in exec command output")
}
return execCredential.Status.Token, nil
}