Skip to content

Commit

Permalink
feat: convert cobra commands from Run to RunE (#111)
Browse files Browse the repository at this point in the history
* feat: convert cobra commands from Run to RunE

---------

Co-authored-by: Radosław Skałbania <[email protected]>
  • Loading branch information
radekska and Radosław Skałbania authored Aug 7, 2024
1 parent 432edd7 commit f1a408b
Show file tree
Hide file tree
Showing 9 changed files with 66 additions and 95 deletions.
57 changes: 22 additions & 35 deletions cmd/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,13 @@ package cmd
import (
"fmt"
"os"
"sync"

"github.com/spf13/cobra"
"golang.org/x/sync/errgroup"

c "github.com/alegrey91/fwdctl/internal/constants"
"github.com/alegrey91/fwdctl/internal/rules"
iptables "github.com/alegrey91/fwdctl/pkg/iptables"
"github.com/spf13/cobra"
)

// applyCmd represents the apply command
Expand All @@ -32,61 +33,47 @@ var applyCmd = &cobra.Command{
Short: "apply rules from file",
Long: `apply rules described in a configuration file`,
Example: c.ProgramName + " apply --file rule.yml",
Run: func(cmd *cobra.Command, args []string) {
RunE: func(cmd *cobra.Command, args []string) error {
rulesContent, err := os.Open(c.RulesFile)
if err != nil {
fmt.Printf("error opening file: %v", err)
os.Exit(1)
return fmt.Errorf("opening file: %v", err)
}
ruleSet, err := rules.NewRuleSetFromFile(rulesContent)
if err != nil {
fmt.Printf("unable to open rules file: %v\n", err)
os.Exit(1)
return fmt.Errorf("unable to open rules file: %v", err)
}
ipt, err := iptables.NewIPTablesInstance()
if err != nil {
fmt.Printf("unable to get iptables instance: %v\n", err)
os.Exit(1)
return fmt.Errorf("unable to get iptables instance: %v", err)
}

var wg sync.WaitGroup
chErr := make(chan error, len(ruleSet.Rules))
chLimit := make(chan int, 10)
g := new(errgroup.Group)
rulesFileIsValid := true

g.SetLimit(10)
for _, rule := range ruleSet.Rules {
wg.Add(1)
// add slot to buffered channel
chLimit <- 1
go func(rule iptables.Rule, wg *sync.WaitGroup, chErr chan error, chLimit chan int) {
err := ipt.ValidateForward(&rule)
wg.Done()
chErr <- err
// free slot from buffered channel
<-chLimit
}(rule, &wg, chErr, chLimit)
r := &rule
g.Go(func() error {
err := ipt.ValidateForward(r)
if err != nil {
rulesFileIsValid = false
}
return err
})
}
go func() {
wg.Wait()
close(chErr)
}()

for err := range chErr {
if err != nil {
fmt.Printf("error validating rule: %v\n", err)
os.Exit(1)
}
if err := g.Wait(); err != nil {
return fmt.Errorf("validating rule: %v", err)
}

if rulesFileIsValid {
for ruleId, rule := range ruleSet.Rules {
err = ipt.CreateForward(&rule)
if err != nil {
fmt.Printf("error applying rule (%s): %v\n", ruleId, err)
os.Exit(1)
if err := ipt.CreateForward(&rule); err != nil {
return fmt.Errorf("applying rule (%s): %v", ruleId, err)
}
}
}
return nil
},
}

Expand Down
13 changes: 5 additions & 8 deletions cmd/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ package cmd

import (
"fmt"
"os"

c "github.com/alegrey91/fwdctl/internal/constants"
iptables "github.com/alegrey91/fwdctl/pkg/iptables"
Expand Down Expand Up @@ -53,18 +52,16 @@ your hypervisor, to external.
+----------------------------+
`,
Example: c.ProgramName + " create -d 3000 -s 192.168.199.105 -p 80",
Run: func(cmd *cobra.Command, args []string) {
RunE: func(cmd *cobra.Command, args []string) error {
ipt, err := iptables.NewIPTablesInstance()
if err != nil {
fmt.Printf("unable to get iptables instance: %v\n", err)
os.Exit(1)
return fmt.Errorf("unable to get iptables instance: %v", err)
}
rule := iptables.NewRule(iface, proto, dport, saddr, sport)
err = ipt.CreateForward(rule)
if err != nil {
fmt.Println(err)
return
if err := ipt.CreateForward(rule); err != nil{
return fmt.Errorf("creating new rule: %v", err)
}
return nil
},
}

Expand Down
9 changes: 4 additions & 5 deletions cmd/daemon_start.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,19 @@ var daemonStartCmd = &cobra.Command{
Use: "start",
Short: "Start fwdctl daemon",
Long: ``,
Run: func(cmd *cobra.Command, args []string) {
RunE: func(cmd *cobra.Command, args []string) error{
ipt, err := iptables.NewIPTablesInstance()
if err != nil {
fmt.Printf("unable to get iptables instance: %v\n", err)
os.Exit(1)
return fmt.Errorf("unable to get iptables instance: %v", err)
}
rulesFile, err := cmd.Flags().GetString("file")
if err != nil {
fmt.Printf("unable to read from flag: %v", err)
os.Exit(1)
return fmt.Errorf("unable to read from flag: %v", err)
}
if res := daemon.Start(ipt, rulesFile); res != 0 {
os.Exit(1)
}
return nil
},
}

Expand Down
36 changes: 14 additions & 22 deletions cmd/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,46 +40,38 @@ var deleteCmd = &cobra.Command{
Long: `Delete forward by passing a rule file or rule id.
`,
Example: c.ProgramName + " delete -n 2",
Run: func(cmd *cobra.Command, args []string) {
RunE: func(cmd *cobra.Command, args []string) error {
ipt, err := iptables.NewIPTablesInstance()
if err != nil {
fmt.Printf("unable to get iptables instance: %v\n", err)
os.Exit(1)
return fmt.Errorf("unable to get iptables instance: %v", err)
}
// Delete rule number
if cmd.Flags().Lookup("id").Changed {
err := ipt.DeleteForwardById(ruleId)
if err != nil {
fmt.Printf("%v\n", err)
os.Exit(1)
if err := ipt.DeleteForwardById(ruleId); err != nil {
return fmt.Errorf("delete forward by ID: %v", err)
}
return
return nil
}

// Loop over file content and delete rule one-by-one.
if cmd.Flags().Lookup("file").Changed {
err := deleteFromFile(ipt, file)
if err != nil {
fmt.Printf("%v\n", err)
os.Exit(1)
if err := deleteFromFile(ipt, file); err != nil {
return fmt.Errorf("delete from file: %v", err)
}
return
return nil
}

if cmd.Flags().Lookup("all").Changed {
err := ipt.DeleteAllForwards()
if err != nil {
fmt.Println(err)
os.Exit(1)
if err := ipt.DeleteAllForwards();err != nil {
return fmt.Errorf("delete all forwards: %v", err)
}
return
return nil
}

err = deleteFromFile(ipt, file)
if err != nil {
fmt.Printf("%v\n", err)
os.Exit(1)
if err = deleteFromFile(ipt, file);err != nil {
return fmt.Errorf("delete from file: %v", err)
}
return nil
},
}

Expand Down
13 changes: 6 additions & 7 deletions cmd/generate_rules.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ package cmd

import (
"fmt"
"os"

"github.com/spf13/cobra"

"github.com/alegrey91/fwdctl/internal/template"
rt "github.com/alegrey91/fwdctl/internal/template/rules_template"
"github.com/spf13/cobra"
)

// generateRulesCmd represents the generateRules command
Expand All @@ -30,13 +30,12 @@ var generateRulesCmd = &cobra.Command{
Short: "generates empty rules file",
Long: `generates empty rules file
`,
Run: func(cmd *cobra.Command, args []string) {
RunE: func(cmd *cobra.Command, args []string) error {
rules := rt.NewRules()
err := template.GenerateTemplate(rules, outputFile)
if err != nil {
fmt.Println(err)
os.Exit(1)
if err := template.GenerateTemplate(rules, outputFile); err != nil {
return fmt.Errorf("generating template: %w", err)
}
return nil
},
}

Expand Down
14 changes: 6 additions & 8 deletions cmd/generate_systemd.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ package cmd

import (
"fmt"
"os"

c "github.com/alegrey91/fwdctl/internal/constants"
"github.com/alegrey91/fwdctl/internal/template"
Expand All @@ -34,17 +33,16 @@ var generateSystemdCmd = &cobra.Command{
Short: "generates systemd service file",
Long: `generates systemd service file to run fwdctl at boot
`,
Run: func(cmd *cobra.Command, args []string) {
RunE: func(cmd *cobra.Command, args []string) error {
systemd, err := st.NewSystemdService(serviceType, installationPath, c.RulesFile)
if err != nil {
fmt.Println(err)
os.Exit(1)
return fmt.Errorf("cannot create systemd service: %v", err)
}
err = template.GenerateTemplate(systemd, outputFile)
if err != nil {
fmt.Printf("error generating templated file: %v\n", err)
os.Exit(1)

if err = template.GenerateTemplate(systemd, outputFile);err != nil {
return fmt.Errorf("generating templated file: %v", err)
}
return nil
},
}

Expand Down
16 changes: 6 additions & 10 deletions cmd/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ package cmd

import (
"fmt"
"os"

c "github.com/alegrey91/fwdctl/internal/constants"
"github.com/alegrey91/fwdctl/internal/printer"
Expand All @@ -36,24 +35,21 @@ var listCmd = &cobra.Command{
Short: "list forwards",
Long: `list forwards made with iptables`,
Example: c.ProgramName + "list -o table",
Run: func(cmd *cobra.Command, args []string) {
RunE: func(cmd *cobra.Command, args []string) error{
ipt, err := iptables.NewIPTablesInstance()
if err != nil {
fmt.Printf("unable to get iptables instance: %v\n", err)
os.Exit(1)
return fmt.Errorf("getting iptables instance: %v", err)
}
ruleList, err := ipt.ListForward(format)
if err != nil {
fmt.Println(err)
return
return fmt.Errorf("listing rules: %v", err)
}

p := printer.NewPrinter(format)
err = p.PrintResult(ruleList)
if err != nil {
fmt.Printf("failed printing results: %v", err)
return
if err = p.PrintResult(ruleList);err != nil {
return fmt.Errorf("printing result: %v", err)
}
return nil
},
}

Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ require (
github.com/spf13/cast v1.5.0 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/subosito/gotenv v1.4.2 // indirect
golang.org/x/sync v0.8.0 // indirect
golang.org/x/sys v0.4.0 // indirect
golang.org/x/text v0.5.0 // indirect
golang.org/x/tools v0.1.12 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,8 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
Expand Down

0 comments on commit f1a408b

Please sign in to comment.