package util import ( "context" "fmt" "strings" "github.com/spf13/cobra" "github.com/wild-cloud/wild-cli/internal/environment" "github.com/wild-cloud/wild-cli/internal/external" "github.com/wild-cloud/wild-cli/internal/output" ) func NewDashboardCommand() *cobra.Command { cmd := &cobra.Command{ Use: "dashboard", Short: "Manage Kubernetes dashboard", Long: `Manage access to the Kubernetes dashboard.`, } cmd.AddCommand( newDashboardTokenCommand(), ) return cmd } func newDashboardTokenCommand() *cobra.Command { return &cobra.Command{ Use: "token", Short: "Get dashboard access token", Long: `Get an access token for the Kubernetes dashboard. This command retrieves the authentication token needed to access the Kubernetes dashboard. Examples: wild dashboard token`, RunE: runDashboardToken, } } func runDashboardToken(cmd *cobra.Command, args []string) error { output.Header("Kubernetes Dashboard Token") // Initialize environment env := environment.New() if err := env.RequiresProject(); err != nil { return err } // Check external tools toolManager := external.NewManager() if err := toolManager.CheckTools(cmd.Context(), []string{"kubectl"}); err != nil { return fmt.Errorf("required tools not available: %w", err) } kubectl := toolManager.Kubectl() // The namespace where the dashboard is installed namespace := "kubernetes-dashboard" secretName := "dashboard-admin-token" // Try to get the token from the secret token, err := getDashboardToken(cmd.Context(), kubectl, namespace, secretName) if err != nil { return fmt.Errorf("failed to get dashboard token: %w", err) } // Print the token with nice formatting output.Success("Use this token to authenticate to the Kubernetes Dashboard:") output.Info("") output.Printf("%s\n", token) output.Info("") // Additional instructions output.Info("Instructions:") output.Info("1. Copy the token above") output.Info("2. Navigate to your Kubernetes Dashboard URL") output.Info("3. Select 'Token' authentication method") output.Info("4. Paste the token and click 'Sign In'") return nil } // getDashboardToken retrieves the dashboard token from Kubernetes func getDashboardToken(ctx context.Context, kubectl *external.KubectlTool, namespace, secretName string) (string, error) { // Try to get the secret directly secretData, err := kubectl.GetResource(ctx, "secret", secretName, namespace) if err != nil { // If secret doesn't exist, try to find any admin-related secret output.Warning("Dashboard admin token secret not found, searching for available tokens...") return findDashboardToken(ctx, kubectl, namespace) } // Extract token from secret data // The secret data is in YAML format, we need to parse it secretStr := string(secretData) lines := strings.Split(secretStr, "\n") for _, line := range lines { if strings.Contains(line, "token:") { // Extract the base64 encoded token parts := strings.Fields(line) if len(parts) >= 2 { encodedToken := parts[1] // Decode base64 token using kubectl tokenBytes, err := kubectl.Execute(ctx, "exec", "deploy/coredns", "-n", "kube-system", "--", "base64", "-d") if err != nil { // Try alternative method with echo and base64 echoCmd := fmt.Sprintf("echo '%s' | base64 -d", encodedToken) tokenBytes, err = kubectl.Execute(ctx, "exec", "deploy/coredns", "-n", "kube-system", "--", "sh", "-c", echoCmd) if err != nil { // Return the encoded token as fallback return encodedToken, nil } } return strings.TrimSpace(string(tokenBytes)), nil } } } return "", fmt.Errorf("token not found in secret data") } // findDashboardToken searches for available dashboard tokens func findDashboardToken(ctx context.Context, kubectl *external.KubectlTool, namespace string) (string, error) { // List all secrets in the dashboard namespace secrets, err := kubectl.GetResource(ctx, "secrets", "", namespace) if err != nil { return "", fmt.Errorf("failed to list secrets in namespace %s: %w", namespace, err) } // Look for tokens in the secret list secretsStr := string(secrets) lines := strings.Split(secretsStr, "\n") var tokenSecrets []string for _, line := range lines { if strings.Contains(line, "token") && strings.Contains(line, "dashboard") { parts := strings.Fields(line) if len(parts) > 0 { tokenSecrets = append(tokenSecrets, parts[0]) } } } if len(tokenSecrets) == 0 { return "", fmt.Errorf("no dashboard token secrets found in namespace %s", namespace) } // Try the first available token secret secretName := tokenSecrets[0] output.Info("Using token secret: " + secretName) return getDashboardToken(ctx, kubectl, namespace, secretName) }