Files
wild-cli/cmd/root.go

135 lines
3.3 KiB
Go

package cmd
import (
"encoding/json"
"fmt"
"os"
"github.com/spf13/cobra"
"gopkg.in/yaml.v3"
"github.com/wild-cloud/wild-central/wild/internal/client"
"github.com/wild-cloud/wild-central/wild/internal/config"
)
var (
apiClient *client.Client
// Global flags
daemonURL string
instanceName string
outputFormat string
)
// rootCmd represents the base command
var rootCmd = &cobra.Command{
Use: "wild",
Short: "Wild Cloud CLI",
Long: `wild-cli is the command-line interface for Wild Central.
It provides a simple way to manage Wild Cloud instances, nodes, clusters,
services, and applications through the Wild Central daemon.`,
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
// Skip for commands that don't need API client
if cmd.Name() == "version" || cmd.Name() == "help" {
return nil
}
// Get daemon URL: flag > env > default
url := daemonURL
if url == "" {
url = config.GetDaemonURL()
}
// Create API client
apiClient = client.NewClient(url)
return nil
},
}
// Execute runs the root command
func Execute() {
if err := rootCmd.Execute(); err != nil {
os.Exit(1)
}
}
func init() {
// Global flags
rootCmd.PersistentFlags().StringVar(&daemonURL, "daemon-url", "", "Daemon URL (default: $WILD_API_URI or http://localhost:5055)")
rootCmd.PersistentFlags().StringVar(&instanceName, "instance", "", "Instance name (overrides current instance)")
rootCmd.PersistentFlags().StringVarP(&outputFormat, "output", "o", "text", "Output format (text, json, yaml)")
// Add subcommands
rootCmd.AddCommand(versionCmd)
rootCmd.AddCommand(daemonCmd)
rootCmd.AddCommand(dnsCmd)
rootCmd.AddCommand(instanceCmd)
rootCmd.AddCommand(configCmd)
rootCmd.AddCommand(secretCmd)
rootCmd.AddCommand(nodeCmd)
rootCmd.AddCommand(pxeCmd)
rootCmd.AddCommand(isoCmd)
rootCmd.AddCommand(clusterCmd)
rootCmd.AddCommand(serviceCmd)
rootCmd.AddCommand(appCmd)
rootCmd.AddCommand(backupCmd)
rootCmd.AddCommand(restoreCmd)
rootCmd.AddCommand(healthCmd)
rootCmd.AddCommand(dashboardCmd)
rootCmd.AddCommand(nodeIPCmd)
rootCmd.AddCommand(operationCmd)
}
// getInstanceName returns the current instance name using the priority cascade
func getInstanceName() (string, error) {
// Create instance lister adapter for API client
var lister config.InstanceLister
if apiClient != nil {
lister = &instanceListerAdapter{client: apiClient}
}
instance, _, err := config.GetCurrentInstance(instanceName, lister)
return instance, err
}
// instanceListerAdapter adapts the API client to the InstanceLister interface
type instanceListerAdapter struct {
client *client.Client
}
func (a *instanceListerAdapter) ListInstances() ([]string, error) {
resp, err := a.client.Get("/api/v1/instances")
if err != nil {
return nil, err
}
instances := resp.GetArray("instances")
result := make([]string, 0, len(instances))
for _, inst := range instances {
if name, ok := inst.(string); ok {
result = append(result, name)
}
}
return result, nil
}
// printJSON prints data as JSON
func printJSON(data interface{}) error {
encoder := json.NewEncoder(os.Stdout)
encoder.SetIndent("", " ")
return encoder.Encode(data)
}
// printYAML prints data as YAML
func printYAML(data interface{}) error {
yamlData, err := yaml.Marshal(data)
if err != nil {
return err
}
fmt.Println(string(yamlData))
return nil
}