162 lines
4.7 KiB
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
|
|
}
|