dyndns/cmd/load-state.go
Torben Nehmer a23043ba5f Added state perstistance
- Define new state directory to hold the last dns update config and push it into the config, default to state/
- Refactoring, move updaterequest into service and out of webapp. Keep only the form parsing there. Specifically, move the processing code into the service package, it shouldn't be in the webapp.
- Add code to load and save the last updaterequest into a state file (watch out to keep the possibly unhashed password out of it).
- Add a command line option to load all available state files given the current configured user list from the command line.
- Refactor user configuartion loading to separate it from user authentication, claen up the code.
- We now require the username in the config, to make handling it in state updates easier. This will allow easier transition to DB style storage anyway.
- Update .gitignore
2021-09-18 15:38:49 +02:00

69 lines
1.8 KiB
Go

package cmd
import (
"fmt"
"io/ioutil"
"log"
"os"
"path"
"gitea.nehmer.net/torben/dyndns/service"
"github.com/spf13/cobra"
)
var cmdLoadState = &cobra.Command{
Use: "load-state",
Short: "Load all state files and process them",
Long: `Loads the state files of all present users and reprocesses them. Use this after
for example a firewall restart or when dyndns data gets lost. It will recreate all
neccessary NFT set and DNS entries based on the last known state.`,
Run: func(cmd *cobra.Command, args []string) {
service.LoadConfig()
if err := loadAndProcessAllStates(); err != nil {
log.Fatalf("Failed to load states: %s", err)
}
log.Println("State processing successful.")
},
}
func init() {
rootCmd.AddCommand(cmdLoadState)
}
func loadAndProcessAllStates() error {
files, err := ioutil.ReadDir(service.C.Users.ConfigDir)
if err != nil {
return fmt.Errorf("failed to list config directory %s: %v",
service.C.Users.ConfigDir, err)
}
for _, file := range files {
configFile := path.Join(service.C.Users.ConfigDir, file.Name())
uc, err := service.LoadConfigFile(configFile)
if err != nil {
return fmt.Errorf("failed to load config file %s: %v", configFile, err)
}
stateFile := uc.GetStateFileName()
if _, err := os.Stat(stateFile); err != nil {
log.Printf("No state file for user %s, skipping (%v)", configFile, err)
continue
}
ur, err := service.LoadStateFile(uc)
if err != nil {
return fmt.Errorf("failed to load sate file %s for user %s: %v",
stateFile, uc.UserName, err)
}
log.Printf("Loaded state file %s:\n%v", stateFile, ur.PrettyPrint())
if err = ur.Process(); err != nil {
return fmt.Errorf("failed to process state file %s for user %s: %v",
stateFile, uc.UserName, err)
}
}
return nil
}