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
This commit is contained in:
		
							
								
								
									
										68
									
								
								cmd/load-state.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								cmd/load-state.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,68 @@
 | 
			
		||||
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
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user