mirror of
https://github.com/netbirdio/netbird.git
synced 2024-12-15 03:11:02 +01:00
182 lines
4.4 KiB
Go
182 lines
4.4 KiB
Go
package cmd
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
log "github.com/sirupsen/logrus"
|
|
"github.com/spf13/cobra"
|
|
"google.golang.org/grpc/status"
|
|
|
|
"github.com/netbirdio/netbird/client/proto"
|
|
)
|
|
|
|
var (
|
|
allFlag bool
|
|
)
|
|
|
|
var stateCmd = &cobra.Command{
|
|
Use: "state",
|
|
Short: "Manage daemon state",
|
|
Long: "Provides commands for managing and inspecting the Netbird daemon state.",
|
|
}
|
|
|
|
var stateListCmd = &cobra.Command{
|
|
Use: "list",
|
|
Aliases: []string{"ls"},
|
|
Short: "List all stored states",
|
|
Long: "Lists all registered states with their status and basic information.",
|
|
Example: " netbird state list",
|
|
RunE: stateList,
|
|
}
|
|
|
|
var stateCleanCmd = &cobra.Command{
|
|
Use: "clean [state-name]",
|
|
Short: "Clean stored states",
|
|
Long: `Clean specific state or all states. The daemon must not be running.
|
|
This will perform cleanup operations and remove the state.`,
|
|
Example: ` netbird state clean dns_state
|
|
netbird state clean --all`,
|
|
RunE: stateClean,
|
|
PreRunE: func(cmd *cobra.Command, args []string) error {
|
|
// Check mutual exclusivity between --all flag and state-name argument
|
|
if allFlag && len(args) > 0 {
|
|
return fmt.Errorf("cannot specify both --all flag and state name")
|
|
}
|
|
if !allFlag && len(args) != 1 {
|
|
return fmt.Errorf("requires a state name argument or --all flag")
|
|
}
|
|
return nil
|
|
},
|
|
}
|
|
|
|
var stateDeleteCmd = &cobra.Command{
|
|
Use: "delete [state-name]",
|
|
Short: "Delete stored states",
|
|
Long: `Delete specific state or all states from storage. The daemon must not be running.
|
|
This will remove the state without performing any cleanup operations.`,
|
|
Example: ` netbird state delete dns_state
|
|
netbird state delete --all`,
|
|
RunE: stateDelete,
|
|
PreRunE: func(cmd *cobra.Command, args []string) error {
|
|
// Check mutual exclusivity between --all flag and state-name argument
|
|
if allFlag && len(args) > 0 {
|
|
return fmt.Errorf("cannot specify both --all flag and state name")
|
|
}
|
|
if !allFlag && len(args) != 1 {
|
|
return fmt.Errorf("requires a state name argument or --all flag")
|
|
}
|
|
return nil
|
|
},
|
|
}
|
|
|
|
func init() {
|
|
rootCmd.AddCommand(stateCmd)
|
|
stateCmd.AddCommand(stateListCmd, stateCleanCmd, stateDeleteCmd)
|
|
|
|
stateCleanCmd.Flags().BoolVarP(&allFlag, "all", "a", false, "Clean all states")
|
|
stateDeleteCmd.Flags().BoolVarP(&allFlag, "all", "a", false, "Delete all states")
|
|
}
|
|
|
|
func stateList(cmd *cobra.Command, _ []string) error {
|
|
conn, err := getClient(cmd)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer func() {
|
|
if err := conn.Close(); err != nil {
|
|
log.Errorf(errCloseConnection, err)
|
|
}
|
|
}()
|
|
|
|
client := proto.NewDaemonServiceClient(conn)
|
|
resp, err := client.ListStates(cmd.Context(), &proto.ListStatesRequest{})
|
|
if err != nil {
|
|
return fmt.Errorf("failed to list states: %v", status.Convert(err).Message())
|
|
}
|
|
|
|
cmd.Printf("\nStored states:\n\n")
|
|
for _, state := range resp.States {
|
|
cmd.Printf("- %s\n", state.Name)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func stateClean(cmd *cobra.Command, args []string) error {
|
|
var stateName string
|
|
if !allFlag {
|
|
stateName = args[0]
|
|
}
|
|
|
|
conn, err := getClient(cmd)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer func() {
|
|
if err := conn.Close(); err != nil {
|
|
log.Errorf(errCloseConnection, err)
|
|
}
|
|
}()
|
|
|
|
client := proto.NewDaemonServiceClient(conn)
|
|
resp, err := client.CleanState(cmd.Context(), &proto.CleanStateRequest{
|
|
StateName: stateName,
|
|
All: allFlag,
|
|
})
|
|
if err != nil {
|
|
return fmt.Errorf("failed to clean state: %v", status.Convert(err).Message())
|
|
}
|
|
|
|
if resp.CleanedStates == 0 {
|
|
cmd.Println("No states were cleaned")
|
|
return nil
|
|
}
|
|
|
|
if allFlag {
|
|
cmd.Printf("Successfully cleaned %d states\n", resp.CleanedStates)
|
|
} else {
|
|
cmd.Printf("Successfully cleaned state %q\n", stateName)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func stateDelete(cmd *cobra.Command, args []string) error {
|
|
var stateName string
|
|
if !allFlag {
|
|
stateName = args[0]
|
|
}
|
|
|
|
conn, err := getClient(cmd)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer func() {
|
|
if err := conn.Close(); err != nil {
|
|
log.Errorf(errCloseConnection, err)
|
|
}
|
|
}()
|
|
|
|
client := proto.NewDaemonServiceClient(conn)
|
|
resp, err := client.DeleteState(cmd.Context(), &proto.DeleteStateRequest{
|
|
StateName: stateName,
|
|
All: allFlag,
|
|
})
|
|
if err != nil {
|
|
return fmt.Errorf("failed to delete state: %v", status.Convert(err).Message())
|
|
}
|
|
|
|
if resp.DeletedStates == 0 {
|
|
cmd.Println("No states were deleted")
|
|
return nil
|
|
}
|
|
|
|
if allFlag {
|
|
cmd.Printf("Successfully deleted %d states\n", resp.DeletedStates)
|
|
} else {
|
|
cmd.Printf("Successfully deleted state %q\n", stateName)
|
|
}
|
|
|
|
return nil
|
|
}
|