158 lines
4.6 KiB
Go
158 lines
4.6 KiB
Go
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)
|
|
}
|