- Created new internal/vaultik package with unified Vaultik struct - Moved all command methods (snapshot, info, prune, verify) from CLI to vaultik package - Implemented single constructor that handles crypto capabilities automatically - Added CanDecrypt() method to check if decryption is available - Updated all CLI commands to use the new vaultik.Vaultik struct - Removed old fragmented App structs and WithCrypto wrapper - Fixed context management - Vaultik now owns its context lifecycle - Cleaned up package imports and dependencies This creates a cleaner separation between CLI/Cobra code and business logic, with all vaultik operations now centralized in the internal/vaultik package.
81 lines
2.4 KiB
Go
81 lines
2.4 KiB
Go
package cli
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
|
|
"github.com/spf13/cobra"
|
|
)
|
|
|
|
// RootFlags holds global flags that apply to all commands.
|
|
// These flags are defined on the root command and inherited by all subcommands.
|
|
type RootFlags struct {
|
|
ConfigPath string
|
|
Verbose bool
|
|
Debug bool
|
|
}
|
|
|
|
var rootFlags RootFlags
|
|
|
|
// NewRootCommand creates the root cobra command for the vaultik CLI.
|
|
// It sets up the command structure, global flags, and adds all subcommands.
|
|
// This is the main entry point for the CLI command hierarchy.
|
|
func NewRootCommand() *cobra.Command {
|
|
cmd := &cobra.Command{
|
|
Use: "vaultik",
|
|
Short: "Secure incremental backup tool with asymmetric encryption",
|
|
Long: `vaultik is a secure incremental backup daemon that encrypts data using age
|
|
public keys and uploads to S3-compatible storage. No private keys are needed
|
|
on the source system.`,
|
|
SilenceUsage: true,
|
|
}
|
|
|
|
// Add global flags
|
|
cmd.PersistentFlags().StringVar(&rootFlags.ConfigPath, "config", "", "Path to config file (default: $VAULTIK_CONFIG or /etc/vaultik/config.yml)")
|
|
cmd.PersistentFlags().BoolVarP(&rootFlags.Verbose, "verbose", "v", false, "Enable verbose output")
|
|
cmd.PersistentFlags().BoolVar(&rootFlags.Debug, "debug", false, "Enable debug output")
|
|
|
|
// Add subcommands
|
|
cmd.AddCommand(
|
|
NewRestoreCommand(),
|
|
NewPruneCommand(),
|
|
NewVerifyCommand(),
|
|
NewFetchCommand(),
|
|
NewStoreCommand(),
|
|
NewSnapshotCommand(),
|
|
NewInfoCommand(),
|
|
)
|
|
|
|
return cmd
|
|
}
|
|
|
|
// GetRootFlags returns the global flags that were parsed from the command line.
|
|
// This allows subcommands to access global flag values like verbosity and config path.
|
|
func GetRootFlags() RootFlags {
|
|
return rootFlags
|
|
}
|
|
|
|
// ResolveConfigPath resolves the config file path from flags, environment, or default.
|
|
// It checks in order: 1) --config flag, 2) VAULTIK_CONFIG environment variable,
|
|
// 3) default location /etc/vaultik/config.yml. Returns an error if no valid
|
|
// config file can be found through any of these methods.
|
|
func ResolveConfigPath() (string, error) {
|
|
// First check global flag
|
|
if rootFlags.ConfigPath != "" {
|
|
return rootFlags.ConfigPath, nil
|
|
}
|
|
|
|
// Then check environment variable
|
|
if envPath := os.Getenv("VAULTIK_CONFIG"); envPath != "" {
|
|
return envPath, nil
|
|
}
|
|
|
|
// Finally check default location
|
|
defaultPath := "/etc/vaultik/config.yml"
|
|
if _, err := os.Stat(defaultPath); err == nil {
|
|
return defaultPath, nil
|
|
}
|
|
|
|
return "", fmt.Errorf("no config file specified, VAULTIK_CONFIG not set, and %s not found", defaultPath)
|
|
}
|