mirror of
https://github.com/psviderski/uncloud.git
synced 2026-08-26 19:13:34 +00:00
uncloud CLI tool and 'machine add' command to bootstrap a new cluster
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
package machine
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/spf13/cobra"
|
||||
"uncloud/internal/cli"
|
||||
)
|
||||
|
||||
type addOptions struct {
|
||||
name string
|
||||
user string
|
||||
port int
|
||||
sshKey string
|
||||
cluster string
|
||||
}
|
||||
|
||||
func NewAddCommand() *cobra.Command {
|
||||
opts := addOptions{}
|
||||
cmd := &cobra.Command{
|
||||
Use: "add HOST",
|
||||
Short: "Add a new machine to a cluster.",
|
||||
Args: cobra.ExactArgs(1),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
uncli := cmd.Context().Value("cli").(*cli.CLI)
|
||||
return add(cmd.Context(), uncli, args[0], opts)
|
||||
},
|
||||
}
|
||||
cmd.Flags().StringVarP(&opts.name, "name", "n", "", "Assign a name to the machine")
|
||||
cmd.Flags().StringVarP(&opts.user, "user", "u", "root", "Username for SSH remote login")
|
||||
cmd.Flags().IntVarP(&opts.port, "port", "p", 22, "Port for SSH remote login")
|
||||
cmd.Flags().StringVarP(&opts.sshKey, "ssh-key", "i", "",
|
||||
"path to SSH private key for SSH remote login (default ~/.ssh/id_*)")
|
||||
cmd.Flags().StringVarP(&opts.cluster, "cluster", "c", "",
|
||||
"Name of the cluster to add the machine to (default is the current cluster)")
|
||||
return cmd
|
||||
}
|
||||
|
||||
func add(ctx context.Context, uncli *cli.CLI, host string, opts addOptions) error {
|
||||
var (
|
||||
cluster *cli.Cluster
|
||||
err error
|
||||
)
|
||||
if opts.cluster == "" {
|
||||
// If the cluster is not specified, use the current cluster. If there are no clusters, create a default one.
|
||||
cluster, err = uncli.GetCurrentCluster()
|
||||
if err != nil {
|
||||
if errors.Is(err, cli.ErrNotFound) {
|
||||
// Do not create a default cluster if there are already clusters but the current cluster is not set.
|
||||
clusters, cErr := uncli.ListClusters()
|
||||
if cErr != nil {
|
||||
return fmt.Errorf("list clusters: %w", cErr)
|
||||
}
|
||||
if len(clusters) > 0 {
|
||||
return errors.New("the current cluster is not set in the Uncloud config. " +
|
||||
"Please specify a cluster with the --cluster flag or set current_cluster in the config")
|
||||
}
|
||||
|
||||
cluster, err = uncli.CreateDefaultCluster()
|
||||
if err != nil {
|
||||
return fmt.Errorf("create default cluster: %w", err)
|
||||
}
|
||||
} else {
|
||||
return fmt.Errorf("get current cluster: %w", err)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cluster, err = uncli.GetCluster(opts.cluster)
|
||||
if err != nil {
|
||||
return fmt.Errorf("get cluster %q: %w", opts.cluster, err)
|
||||
}
|
||||
}
|
||||
|
||||
name, err := cluster.AddMachine(ctx, opts.name, opts.user, host, opts.port, opts.sshKey)
|
||||
if err != nil {
|
||||
return fmt.Errorf("add machine to cluster %q: %w", cluster.Name, err)
|
||||
}
|
||||
fmt.Printf("Machine %q added to cluster %q\n", name, cluster.Name)
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package machine
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func NewRootCommand() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "machine",
|
||||
Short: "Manage machines in an Uncloud cluster.",
|
||||
}
|
||||
cmd.AddCommand(
|
||||
NewAddCommand(),
|
||||
)
|
||||
return cmd
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/spf13/cobra"
|
||||
"os"
|
||||
"strings"
|
||||
"uncloud/cmd/uncloud/machine"
|
||||
"uncloud/internal/cli"
|
||||
)
|
||||
|
||||
func main() {
|
||||
var configPath string
|
||||
cmd := &cobra.Command{
|
||||
Use: "uncloud",
|
||||
Short: "A CLI tool for managing Uncloud resources such as clusters, machines, and services.",
|
||||
SilenceUsage: true,
|
||||
SilenceErrors: true,
|
||||
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
|
||||
if strings.HasPrefix(configPath, "~/") {
|
||||
home, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
return fmt.Errorf("get user home directory to resolve %q: %w", configPath, err)
|
||||
}
|
||||
configPath = strings.Replace(configPath, "~", home, 1)
|
||||
}
|
||||
|
||||
uncli, err := cli.New(configPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("initialize CLI: %w", err)
|
||||
}
|
||||
cmd.SetContext(context.WithValue(cmd.Context(), "cli", uncli))
|
||||
return nil
|
||||
},
|
||||
}
|
||||
// TODO: allow to override using UNCLOUD_CONFIG env var.
|
||||
cmd.PersistentFlags().StringVar(&configPath, "uncloud-config", "~/.config/uncloud/config.toml",
|
||||
"path to the Uncloud configuration file")
|
||||
_ = cmd.MarkPersistentFlagFilename("uncloud-config", "toml")
|
||||
|
||||
cmd.AddCommand(
|
||||
machine.NewRootCommand(),
|
||||
)
|
||||
cobra.CheckErr(cmd.Execute())
|
||||
}
|
||||
Reference in New Issue
Block a user