Files
wild-cloud/wild-cli/cmd/wild/cluster/config.go

162 lines
4.7 KiB
Go

package cluster
import (
"fmt"
"os"
"path/filepath"
"github.com/spf13/cobra"
"github.com/wild-cloud/wild-cli/internal/config"
"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 newConfigCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "config",
Short: "Manage cluster configuration",
Long: `Generate and manage cluster configuration files.`,
}
cmd.AddCommand(
newConfigGenerateCommand(),
)
return cmd
}
func newConfigGenerateCommand() *cobra.Command {
return &cobra.Command{
Use: "generate",
Short: "Generate cluster configuration",
Long: `Generate Talos configuration files for the cluster.
This command creates initial cluster secrets and configuration files using talosctl.
Examples:
wild cluster config generate`,
RunE: runConfigGenerate,
}
}
func runConfigGenerate(cmd *cobra.Command, args []string) error {
output.Header("Talos Cluster Configuration Generation")
// 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{"talosctl"}); err != nil {
return fmt.Errorf("required tools not available: %w", err)
}
// Load configuration
configMgr := config.NewManager(env.ConfigPath(), env.SecretsPath())
// Ensure required directories exist
nodeSetupDir := filepath.Join(env.WildCloudDir(), "setup", "cluster-nodes")
generatedDir := filepath.Join(nodeSetupDir, "generated")
// Check if generated directory already exists and has content
if entries, err := os.ReadDir(generatedDir); err == nil && len(entries) > 0 {
output.Success("Cluster configuration already exists in " + generatedDir)
output.Info("Skipping cluster configuration generation")
return nil
}
if err := os.MkdirAll(generatedDir, 0755); err != nil {
return fmt.Errorf("creating generated directory: %w", err)
}
// Get required configuration values
clusterName, err := getRequiredConfig(configMgr, "cluster.name", "wild-cluster")
if err != nil {
return err
}
vip, err := getRequiredConfig(configMgr, "cluster.nodes.control.vip", "")
if err != nil {
return err
}
output.Info("Generating new cluster secrets...")
// Remove existing secrets directory if it exists
if _, err := os.Stat(generatedDir); err == nil {
output.Warning("Removing existing secrets directory...")
if err := os.RemoveAll(generatedDir); err != nil {
return fmt.Errorf("removing existing generated directory: %w", err)
}
}
if err := os.MkdirAll(generatedDir, 0755); err != nil {
return fmt.Errorf("creating generated directory: %w", err)
}
// Generate cluster configuration
output.Info("Generating initial cluster configuration...")
output.Info("Cluster name: " + clusterName)
output.Info("Control plane endpoint: https://" + vip + ":6443")
// Change to generated directory for talosctl operations
oldDir, err := os.Getwd()
if err != nil {
return fmt.Errorf("getting current directory: %w", err)
}
if err := os.Chdir(generatedDir); err != nil {
return fmt.Errorf("changing to generated directory: %w", err)
}
defer func() {
_ = os.Chdir(oldDir)
}()
talosctl := toolManager.Talosctl()
// Generate secrets first
if err := talosctl.GenerateSecrets(cmd.Context()); err != nil {
return fmt.Errorf("generating secrets: %w", err)
}
// Generate configuration with secrets
endpoint := "https://" + vip + ":6443"
if err := talosctl.GenerateConfigWithSecrets(cmd.Context(), clusterName, endpoint, "secrets.yaml"); err != nil {
return fmt.Errorf("generating config with secrets: %w", err)
}
output.Success("Cluster configuration generation completed!")
output.Info("Generated files in: " + generatedDir)
output.Info(" - controlplane.yaml # Control plane node configuration")
output.Info(" - worker.yaml # Worker node configuration")
output.Info(" - talosconfig # Talos client configuration")
output.Info(" - secrets.yaml # Cluster secrets")
return nil
}
// getRequiredConfig gets a required configuration value, prompting if not set
func getRequiredConfig(configMgr *config.Manager, path, defaultValue string) (string, error) {
value, err := configMgr.Get(path)
if err != nil || value == nil || value.(string) == "" {
if defaultValue != "" {
output.Warning(fmt.Sprintf("Config '%s' not set, using default: %s", path, defaultValue))
return defaultValue, nil
} else {
return "", fmt.Errorf("required configuration '%s' not set", path)
}
}
strValue, ok := value.(string)
if !ok {
return "", fmt.Errorf("configuration '%s' is not a string", path)
}
return strValue, nil
}