From 29581b56d81530d2740af56fca6e9293833176d5 Mon Sep 17 00:00:00 2001 From: Nikhil Malik Date: Tue, 27 Feb 2024 10:44:43 +0900 Subject: [PATCH] BFD config save and apply added --- cmd/dump/apply.go | 37 ++++++++++++++++++- cmd/dump/save.go | 22 ++++++++++- cmd/get/get_bfd.go | 91 +++++++++++++++++++++++++++++++++++++++++++++- cmd/root.go | 4 +- 4 files changed, 148 insertions(+), 6 deletions(-) diff --git a/cmd/dump/apply.go b/cmd/dump/apply.go index 3c1603c..f0600cb 100644 --- a/cmd/dump/apply.go +++ b/cmd/dump/apply.go @@ -21,6 +21,7 @@ import ( "errors" "fmt" "loxicmd/cmd/create" + "loxicmd/cmd/set" "loxicmd/pkg/api" "os" "os/exec" @@ -36,6 +37,7 @@ type ApplyOptions struct { SessionUlClConfigFile string FWConfigFile string NormalConfigFile string + BFDConfigFile string Intf string ConfigPath string Route bool @@ -56,8 +58,10 @@ func ApplyCmd(options *ApplyOptions, restOptions *api.RESTOptions) *cobra.Comman len(options.SessionUlClConfigFile) == 0 && len(options.FWConfigFile) == 0 && len(options.Intf) == 0 && - len(options.NormalConfigFile) == 0 { + len(options.NormalConfigFile) == 0 && + len(options.BFDConfigFile) == 0 { fmt.Println("Provide valid options") + cmd.Help() return } if len(options.IpConfigFile) > 0 { @@ -91,6 +95,10 @@ func ApplyCmd(options *ApplyOptions, restOptions *api.RESTOptions) *cobra.Comman ApplyFWConfig(options.FWConfigFile, restOptions) fmt.Printf("Configuration applied - %s\n", options.FWConfigFile) } + if len(options.BFDConfigFile) > 0 { + ApplyBFDConfig(options.BFDConfigFile, restOptions) + fmt.Printf("Configuration applied - %s\n", options.BFDConfigFile) + } if len(options.NormalConfigFile) > 0 { if err := ApplyFileConfig(options.NormalConfigFile, restOptions); err != nil { fmt.Printf("Configuration failed - %s\n", options.NormalConfigFile) @@ -676,3 +684,30 @@ func ApplyFWConfig(file string, restOptions *api.RESTOptions) { defer resp.Body.Close() } } + +func ApplyBFDConfig(file string, restOptions *api.RESTOptions) { + // open file + var resp api.BFDSessionGet + byteBuf, err := os.ReadFile(file) + if err != nil { + fmt.Println(err.Error()) + return + } + + // Unmashal to Json + if err := json.Unmarshal(byteBuf, &resp); err != nil { + fmt.Printf("Error: Failed to unmarshal File: (%s)\n", err.Error()) + return + } + + // POST the dump + for _, b := range resp.BFDSessionAttr { + fmt.Printf("bfd: %v\n", b) + resp, err := set.SetBFDAPICall(restOptions, b) + if err != nil { + fmt.Printf("Error: %s\n", err.Error()) + return + } + defer resp.Body.Close() + } +} \ No newline at end of file diff --git a/cmd/dump/save.go b/cmd/dump/save.go index 4b3bb97..307145a 100644 --- a/cmd/dump/save.go +++ b/cmd/dump/save.go @@ -32,6 +32,7 @@ type SaveOptions struct { SaveUlClConfig bool SaveFWConfig bool SaveEPConfig bool + SaveBFDConfig bool SaveAllConfig bool } @@ -45,6 +46,14 @@ func SaveCmd(saveOpts *SaveOptions, restOptions *api.RESTOptions) *cobra.Command _ = cmd _ = args dpath := "/etc/loxilb/" + if (!saveOpts.SaveIpConfig && !saveOpts.SaveAllConfig && + !saveOpts.SaveLBConfig && !saveOpts.SaveSessionConfig && + !saveOpts.SaveUlClConfig && !saveOpts.SaveFWConfig && + !saveOpts.SaveEPConfig && !saveOpts.SaveBFDConfig) { + fmt.Println("Provide valid options") + cmd.Help() + return + } if _, err := os.Stat(dpath); errors.Is(err, os.ErrNotExist) { err := os.Mkdir(dpath, os.ModePerm) if err != nil { @@ -93,12 +102,21 @@ func SaveCmd(saveOpts *SaveOptions, restOptions *api.RESTOptions) *cobra.Command fmt.Println("Firewall Configuration saved in", FWFile) } if saveOpts.SaveEPConfig || saveOpts.SaveAllConfig { - FWFile, err := get.EPdump(restOptions, dpath) + EPFile, err := get.EPdump(restOptions, dpath) + if err != nil { + fmt.Println(err.Error()) + return + } + fmt.Println("EndPoint Configuration saved in", EPFile) + } + if saveOpts.SaveBFDConfig || saveOpts.SaveAllConfig { + fmt.Println("Saving BFD Configuration...") + BFDFile, err := get.BFDdump(restOptions, dpath) if err != nil { fmt.Println(err.Error()) return } - fmt.Println("EndPoint Configuration saved in", FWFile) + fmt.Println("BFD Configuration saved in", BFDFile) } }, } diff --git a/cmd/get/get_bfd.go b/cmd/get/get_bfd.go index 12021d7..58bddf2 100644 --- a/cmd/get/get_bfd.go +++ b/cmd/get/get_bfd.go @@ -23,6 +23,10 @@ import ( "loxicmd/pkg/api" "net/http" "time" + "strings" + "os" + "os/exec" + "errors" "github.com/spf13/cobra" ) @@ -81,7 +85,7 @@ func PrintGetBFDResult(resp *http.Response, o api.RESTOptions) { // Table Init table := TableInit() - // Making load balance data + // Making data for _, bfd := range BFDresp.BFDSessionAttr { if (o.PrintOption == "wide") { table.SetHeader(BFD_WIDE_TITLE) @@ -92,6 +96,89 @@ func PrintGetBFDResult(resp *http.Response, o api.RESTOptions) { data = append(data, []string{bfd.Instance, bfd.RemoteIP, bfd.State}) } } - // Rendering the load balance data to table + // Rendering the data to table TableShow(data, table) +} + +func BFDdump(restOptions *api.RESTOptions, path string) (string, error) { + BFDresp := api.BFDSessionGet{} + + // File Open + fileP := []string{"BFDconfig_", ".txt"} + t := time.Now() + file := strings.Join(fileP, t.Local().Format("2006-01-02_15:04:05")) + f, err := os.Create(file) + if err != nil { + fmt.Printf("Can't create dump file\n") + os.Exit(1) + } + defer f.Close() + + client := api.NewLoxiClient(restOptions) + ctx := context.TODO() + var cancel context.CancelFunc + if restOptions.Timeout > 0 { + ctx, cancel = context.WithTimeout(context.TODO(), time.Duration(restOptions.Timeout)*time.Second) + defer cancel() + } + resp, err := client.Status().SetUrl("config/bfd/all").Get(ctx) + if err != nil { + fmt.Printf("Error: %s\n", err.Error()) + return "", err + } + if resp.StatusCode == http.StatusOK { + + resultByte, err := io.ReadAll(resp.Body) + if err != nil { + fmt.Printf("Error: Failed to read HTTP response: (%s)\n", err.Error()) + return "", err + } + + if err := json.Unmarshal(resultByte, &BFDresp); err != nil { + fmt.Printf("Error: Failed to unmarshal HTTP response: (%s)\n", err.Error()) + return "", err + } + + bfds := api.BFDSessionGet{} + bfds.BFDSessionAttr = BFDresp.BFDSessionAttr + /* + for _, b := range BFDresp.BFDSessionAttr { + bfds.BFDSessionAttr = append(bfds.BFDSessionAttr, b) + + data = append(data, []string{bfd.Instance, bfd.RemoteIP, bfd.SourceIP, + fmt.Sprintf("%d",bfd.Port), fmt.Sprintf("%d us",bfd.Interval), fmt.Sprintf("%d",bfd.RetryCount), bfd.State}) + } */ + cfgResultByte, err := json.Marshal(bfds) + if err != nil { + fmt.Printf("Error: Failed to marshal BFD Cfg: (%s)\n", err.Error()) + return "", err + } + + // Write + f.Write(cfgResultByte) + cfile := path + "BFDconfig.txt" + if _, err := os.Stat(cfile); errors.Is(err, os.ErrNotExist) { + if err != nil { + fmt.Println("There is no saved config file") + } + } else { + command := "mv " + cfile + " " + cfile + ".bk" + cmd := exec.Command("bash", "-c", command) + _, err := cmd.Output() + if err != nil { + fmt.Println("Can't backup ", cfile) + return file, err + } + } + command := "cp -R " + file + " " + cfile + cmd := exec.Command("bash", "-c", command) + fmt.Println(cmd) + _, err = cmd.Output() + if err != nil { + fmt.Println("Failed copy file to", cfile) + return file, err + } + return file, nil + } + return "", err } \ No newline at end of file diff --git a/cmd/root.go b/cmd/root.go index 193abb8..8bbfa79 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -101,8 +101,9 @@ loxicmd aim to provide all of the configuation for the loxilb.`, saveCmd.Flags().BoolVarP(&saveOptions.SaveUlClConfig, "ulcl", "", false, "Saves ulcl configuration") saveCmd.Flags().BoolVarP(&saveOptions.SaveFWConfig, "firewall", "", false, "Saves firewall configuration") saveCmd.Flags().BoolVarP(&saveOptions.SaveEPConfig, "endpoint", "", false, "Saves endpoint configuration") + saveCmd.Flags().BoolVarP(&saveOptions.SaveBFDConfig, "bfd", "", false, "Saves BFD configuration") - saveCmd.MarkFlagsMutuallyExclusive("all", "ip", "lb", "session", "ulcl", "firewall", "endpoint") + saveCmd.MarkFlagsMutuallyExclusive("all", "ip", "lb", "session", "ulcl", "firewall", "endpoint", "bfd") applyCmd.Flags().StringVarP(&applyOptions.IpConfigFile, "ip", "i", "", "IP config file to apply") applyCmd.Flags().StringVarP(&applyOptions.Intf, "per-intf", "", "", "Apply configuration only for specific interface") @@ -113,6 +114,7 @@ loxicmd aim to provide all of the configuation for the loxilb.`, applyCmd.Flags().StringVarP(&applyOptions.SessionUlClConfigFile, "ulcl", "", "", "Ulcl config file to apply") applyCmd.Flags().StringVarP(&applyOptions.FWConfigFile, "firewall", "", "", "Firewall config file to apply") applyCmd.Flags().StringVarP(&applyOptions.NormalConfigFile, "file", "f", "", "Config file to apply as like K8s") + applyCmd.Flags().StringVarP(&applyOptions.BFDConfigFile, "bfd", "", "", "BFD Config file to apply") rootCmd.AddCommand(saveCmd) rootCmd.AddCommand(applyCmd)