Remove commands that belong to Wild Central (dns, proxy, firewall, ddns, crowdsec, secret central) since those APIs live on Central now. Merge service into app (install, logs, config), merge iso into asset (delete), move orphan commands (health, node-ip) under cluster. Clean up redundant commands (backup start, node cancel-discovery) and standardize deletion confirmation on --yes/-y across all commands.
278 lines
7.0 KiB
Go
278 lines
7.0 KiB
Go
package cmd
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
|
|
"github.com/spf13/cobra"
|
|
|
|
"github.com/wild-cloud/wild-central/wild/internal/config"
|
|
)
|
|
|
|
var instanceCmd = &cobra.Command{
|
|
Use: "instance",
|
|
Short: "Manage instances",
|
|
Long: `Create, list, and manage Wild Cloud instances.`,
|
|
}
|
|
|
|
var instanceCreateCmd = &cobra.Command{
|
|
Use: "create <name>",
|
|
Short: "Create a new instance",
|
|
Args: cobra.ExactArgs(1),
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
name := args[0]
|
|
|
|
resp, err := apiClient.Post("/api/v1/instances", map[string]string{
|
|
"name": name,
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
fmt.Printf("Instance '%s' created successfully\n", name)
|
|
if msg, ok := resp.Data["message"].(string); ok && msg != "" {
|
|
fmt.Println(msg)
|
|
}
|
|
return nil
|
|
},
|
|
}
|
|
|
|
var instanceListCmd = &cobra.Command{
|
|
Use: "list",
|
|
Short: "List all instances",
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
resp, err := apiClient.Get("/api/v1/instances")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if outputFormat == "json" {
|
|
return printJSON(resp.Data)
|
|
}
|
|
|
|
if outputFormat == "yaml" {
|
|
return printYAML(resp.Data)
|
|
}
|
|
|
|
instances := resp.GetArray("instances")
|
|
if len(instances) == 0 {
|
|
fmt.Println("No instances found")
|
|
return nil
|
|
}
|
|
|
|
fmt.Println("INSTANCES:")
|
|
for _, inst := range instances {
|
|
if name, ok := inst.(string); ok {
|
|
fmt.Printf(" - %s\n", name)
|
|
}
|
|
}
|
|
return nil
|
|
},
|
|
}
|
|
|
|
var instanceShowCmd = &cobra.Command{
|
|
Use: "show <name>",
|
|
Short: "Show instance details",
|
|
Args: cobra.ExactArgs(1),
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
name := args[0]
|
|
|
|
resp, err := apiClient.Get(fmt.Sprintf("/api/v1/instances/%s", name))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if outputFormat == "json" {
|
|
return printJSON(resp.Data)
|
|
}
|
|
|
|
if outputFormat == "yaml" {
|
|
return printYAML(resp.Data)
|
|
}
|
|
|
|
// Pretty print instance info
|
|
instanceName := resp.GetString("name")
|
|
if instanceName != "" {
|
|
fmt.Printf("Instance: %s\n", instanceName)
|
|
}
|
|
|
|
// Show key config values
|
|
if config := resp.GetMap("config"); config != nil {
|
|
// Check for cloud config (test-cloud structure)
|
|
if cloud, ok := config["cloud"].(map[string]any); ok {
|
|
if domain, ok := cloud["domain"].(string); ok && domain != "" {
|
|
fmt.Printf("Domain: %s\n", domain)
|
|
}
|
|
if baseDomain, ok := cloud["baseDomain"].(string); ok && baseDomain != "" {
|
|
fmt.Printf("Base Domain: %s\n", baseDomain)
|
|
}
|
|
} else {
|
|
// Check for direct config fields (test-cli structure)
|
|
if domain, ok := config["domain"].(string); ok && domain != "" {
|
|
fmt.Printf("Domain: %s\n", domain)
|
|
}
|
|
if baseDomain, ok := config["baseDomain"].(string); ok && baseDomain != "" {
|
|
fmt.Printf("Base Domain: %s\n", baseDomain)
|
|
}
|
|
}
|
|
|
|
// Show cluster info if available
|
|
if cluster, ok := config["cluster"].(map[string]any); ok {
|
|
if clusterName, ok := cluster["name"].(string); ok && clusterName != "" {
|
|
fmt.Printf("Cluster Name: %s\n", clusterName)
|
|
}
|
|
}
|
|
}
|
|
|
|
fmt.Println("\nUse -o json or -o yaml for full configuration")
|
|
return nil
|
|
},
|
|
}
|
|
|
|
var instanceDeleteConfirm bool
|
|
|
|
var instanceDeleteCmd = &cobra.Command{
|
|
Use: "delete <name>",
|
|
Short: "Delete an instance",
|
|
Args: cobra.ExactArgs(1),
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
name := args[0]
|
|
|
|
if !instanceDeleteConfirm {
|
|
fmt.Printf("Are you sure you want to delete instance '%s'? (y/N): ", name)
|
|
var confirm string
|
|
fmt.Scanln(&confirm)
|
|
if confirm != "y" && confirm != "Y" {
|
|
fmt.Println("Deletion cancelled")
|
|
return nil
|
|
}
|
|
}
|
|
|
|
resp, err := apiClient.Delete(fmt.Sprintf("/api/v1/instances/%s", name))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
fmt.Printf("Instance '%s' deleted successfully\n", name)
|
|
if msg, ok := resp.Data["message"].(string); ok && msg != "" {
|
|
fmt.Println(msg)
|
|
}
|
|
return nil
|
|
},
|
|
}
|
|
|
|
var instanceCurrentCmd = &cobra.Command{
|
|
Use: "current",
|
|
Short: "Show current instance",
|
|
Long: `Display the instance that would be used by commands.
|
|
|
|
Resolution order:
|
|
1. --instance flag
|
|
2. ~/.wildcloud/current_instance file
|
|
3. Auto-select first available instance`,
|
|
Run: func(cmd *cobra.Command, args []string) {
|
|
inst, err := getInstanceName()
|
|
if err != nil {
|
|
fmt.Printf("Error: %v\n", err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
fmt.Println(inst)
|
|
},
|
|
}
|
|
|
|
var instanceUseCmd = &cobra.Command{
|
|
Use: "use <name>",
|
|
Short: "Set the default instance",
|
|
Long: `Set the default instance to use for all commands.
|
|
|
|
This persists the instance selection to ~/.wildcloud/current_instance.
|
|
The instance can still be overridden with the --instance flag.`,
|
|
Args: cobra.ExactArgs(1),
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
instanceToSet := args[0]
|
|
|
|
// Validate instance exists by calling API
|
|
resp, err := apiClient.Get(fmt.Sprintf("/api/v1/instances/%s", instanceToSet))
|
|
if err != nil {
|
|
return fmt.Errorf("instance '%s' not found: %w", instanceToSet, err)
|
|
}
|
|
|
|
// Verify we got a valid response
|
|
if name := resp.GetString("name"); name != instanceToSet {
|
|
return fmt.Errorf("instance '%s' not found", instanceToSet)
|
|
}
|
|
|
|
// Persist the selection
|
|
if err := config.SetCurrentInstance(instanceToSet); err != nil {
|
|
return fmt.Errorf("failed to set current instance: %w", err)
|
|
}
|
|
|
|
fmt.Printf("Switched to instance: %s\n", instanceToSet)
|
|
|
|
// Check for config files and provide hint
|
|
dataDir := config.GetWildCLIDataDir()
|
|
|
|
var hasConfigs bool
|
|
if _, err := os.Stat(config.GetTalosconfigPath(dataDir, instanceToSet)); err == nil {
|
|
hasConfigs = true
|
|
}
|
|
if _, err := os.Stat(config.GetKubeconfigPath(dataDir, instanceToSet)); err == nil {
|
|
hasConfigs = true
|
|
}
|
|
|
|
if hasConfigs {
|
|
fmt.Println("\nTo configure your environment, run:")
|
|
fmt.Println(" source <(wild instance env)")
|
|
}
|
|
|
|
return nil
|
|
},
|
|
}
|
|
|
|
var instanceEnvCmd = &cobra.Command{
|
|
Use: "env",
|
|
Short: "Output environment variables for current instance",
|
|
Long: `Output export commands for TALOSCONFIG and KUBECONFIG.
|
|
|
|
Usage:
|
|
source <(wild instance env)
|
|
|
|
This will set environment variables for the current instance's talosconfig and kubeconfig files if they exist.`,
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
// Get current instance
|
|
inst, err := getInstanceName()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Check for talosconfig and kubeconfig files
|
|
dataDir := config.GetWildCLIDataDir()
|
|
|
|
// Check for talosconfig
|
|
talosconfigPath := config.GetTalosconfigPath(dataDir, inst)
|
|
if _, err := os.Stat(talosconfigPath); err == nil {
|
|
fmt.Printf("export TALOSCONFIG=%s\n", talosconfigPath)
|
|
}
|
|
|
|
// Check for kubeconfig
|
|
kubeconfigPath := config.GetKubeconfigPath(dataDir, inst)
|
|
if _, err := os.Stat(kubeconfigPath); err == nil {
|
|
fmt.Printf("export KUBECONFIG=%s\n", kubeconfigPath)
|
|
}
|
|
|
|
return nil
|
|
},
|
|
}
|
|
|
|
func init() {
|
|
instanceCmd.AddCommand(instanceCreateCmd)
|
|
instanceCmd.AddCommand(instanceListCmd)
|
|
instanceCmd.AddCommand(instanceShowCmd)
|
|
instanceCmd.AddCommand(instanceDeleteCmd)
|
|
instanceDeleteCmd.Flags().BoolVarP(&instanceDeleteConfirm, "yes", "y", false, "Skip confirmation prompt")
|
|
instanceCmd.AddCommand(instanceCurrentCmd)
|
|
instanceCmd.AddCommand(instanceUseCmd)
|
|
instanceCmd.AddCommand(instanceEnvCmd)
|
|
}
|