diff --git a/cmd/caplance/caplance.go b/cmd/caplance/caplance.go index 9e41330..6c11717 100644 --- a/cmd/caplance/caplance.go +++ b/cmd/caplance/caplance.go @@ -1,21 +1,7 @@ package main -import ( - "flag" - "os" - - "github.com/pwpon500/caplance/pkg/setups" -) - -var ( - setupName = flag.String("setup", "", "name of test setup to create") - teardownFlag = flag.Bool("teardown", false, "run teardown instead of build setup") -) +import "github.com/pwpon500/caplance/cmd/caplance/cmd" func main() { - flag.Parse() - if *setupName != "" { - setups.RunSetup(*setupName, *teardownFlag) - os.Exit(0) - } + cmd.Execute() } diff --git a/cmd/caplance/cmd/client.go b/cmd/caplance/cmd/client.go new file mode 100644 index 0000000..b4c3dde --- /dev/null +++ b/cmd/caplance/cmd/client.go @@ -0,0 +1,42 @@ +package cmd + +import ( + "log" + "net" + + "github.com/pwpon500/caplance/internal/client" + "github.com/spf13/cobra" +) + +func init() { + rootCmd.AddCommand(clientCmd) +} + +var clientCmd = &cobra.Command{ + Use: "client", + Short: "Start caplance in client mode", + Long: `Mark this host as a backend, allowing packets to be forwarded to it from the load balancer.`, + Run: func(cmd *cobra.Command, args []string) { + readConfig() + vip := net.ParseIP(conf.VIP) + if vip == nil { + log.Fatal("Could not parse vip: " + conf.VIP) + } + dataIP := net.ParseIP(conf.Client.DataIP) + if dataIP == nil { + log.Fatal("Could not parse data ip: " + conf.Client.DataIP) + } + c := client.NewClient(vip, dataIP) + connectIP := net.ParseIP(conf.Client.ConnectIP) + if connectIP == nil { + connectIP = net.ParseIP(conf.Server.MngIP) + if connectIP == nil { + log.Fatalf("Could not parse Client.ConnectIP (%v) or Server.MngIP (%v)\n", conf.Client.ConnectIP, conf.Server.MngIP) + } + } + err := c.Start(connectIP) + if err != nil { + log.Fatal("Failed to start with error: " + err.Error()) + } + }, +} diff --git a/cmd/caplance/cmd/root.go b/cmd/caplance/cmd/root.go new file mode 100644 index 0000000..4adb03c --- /dev/null +++ b/cmd/caplance/cmd/root.go @@ -0,0 +1,82 @@ +package cmd + +import ( + "fmt" + "log" + "os" + + "github.com/spf13/cobra" + "github.com/spf13/viper" +) + +type config struct { + Client struct { + ConnectIP string + DataIP string + } + Server struct { + MngIP string + BackendCapacity int + } + VIP string + Test bool + + HealthRate int + RegisterTimeout int + ReadTimeout int + WriteTimeout int + + Sockaddr string +} + +var ( + conf *config + configLocation string +) + +// Execute starts the cobra chain +func Execute() { + if err := rootCmd.Execute(); err != nil { + fmt.Println(err) + os.Exit(1) + } +} + +func init() { + viper.AddConfigPath(".") + viper.AddConfigPath("/etc/caplance/") + viper.SetConfigName("caplance.cfg") + + viper.SetDefault("Test", false) + viper.SetDefault("HealthRate", 20) + viper.SetDefault("RegisterTimeout", 10) + viper.SetDefault("ReadTimeout", 30) + viper.SetDefault("WriteTimeout", 10) + viper.SetDefault("Sockaddr", "/var/run/caplance.sock") + + rootCmd.PersistentFlags().StringVarP(&configLocation, "file", "f", "", "choose a non-standard config location") + +} + +func readConfig() { + if configLocation != "" { + viper.SetConfigFile(configLocation) + } + + err := viper.ReadInConfig() + if err != nil { + log.Fatal("Failed to read in config: " + err.Error()) + } + + conf = &config{} + err = viper.Unmarshal(conf) + if err != nil { + log.Fatal("Failed to unmarshal config into struct: " + err.Error()) + } +} + +var rootCmd = &cobra.Command{ + Use: "caplancectl", + Short: "caplancectl is the controller for caplance", + Long: `For more information, visit https://github.com/Pwpon500/caplance`, +} diff --git a/cmd/caplance/cmd/server.go b/cmd/caplance/cmd/server.go new file mode 100644 index 0000000..5c4fcac --- /dev/null +++ b/cmd/caplance/cmd/server.go @@ -0,0 +1,39 @@ +package cmd + +import ( + "log" + "net" + "strconv" + + "github.com/pwpon500/caplance/internal/balancer" + "github.com/spf13/cobra" +) + +func init() { + rootCmd.AddCommand(serverCmd) +} + +var serverCmd = &cobra.Command{ + Use: "server", + Short: "Start caplance in server mode", + Long: `Mark this host as the load balancer, forwarding packets to a set of backends.`, + Run: func(cmd *cobra.Command, args []string) { + readConfig() + vip := net.ParseIP(conf.VIP) + if vip == nil { + log.Fatal("Could not parse vip: " + conf.VIP) + } + mngIP := net.ParseIP(conf.Server.MngIP) + if mngIP == nil { + log.Fatal("Could not parse management ip: " + conf.Server.MngIP) + } + if conf.Server.BackendCapacity <= 0 { + log.Fatal("Backend capacity " + strconv.Itoa(conf.Server.BackendCapacity) + " must be postive.") + } + b, err := balancer.New(vip, mngIP, conf.Server.BackendCapacity) + if err != nil { + log.Fatal("Error when creating balancer: " + err.Error()) + } + b.Start() + }, +} diff --git a/go.mod b/go.mod index 37445ce..478c8e5 100644 --- a/go.mod +++ b/go.mod @@ -12,6 +12,7 @@ require ( github.com/kr/pty v1.1.4 // indirect github.com/mdlayher/raw v0.0.0-20190419142535-64193704e472 // indirect github.com/spf13/cobra v0.0.5 + github.com/spf13/viper v1.3.2 github.com/stamblerre/gocode v0.0.0-20190327203809-810592086997 // indirect github.com/vishvananda/netlink v1.0.0 github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc // indirect diff --git a/go.sum b/go.sum index 6e5ce3a..9f376e6 100644 --- a/go.sum +++ b/go.sum @@ -10,9 +10,11 @@ github.com/coreos/go-iptables v0.4.1 h1:TyEMaK2xD/EcB0385QcvX/OvI2XI7s4SJEI2EhZF github.com/coreos/go-iptables v0.4.1/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dchest/siphash v1.2.1 h1:4cLinnzVJDKxTCl9B01807Yiy+W7ZzVHj/KIroQRvT4= github.com/dchest/siphash v1.2.1/go.mod h1:q+IRvb2gOSrUnYoPqHiyHXS0FOBBOdl6tONBlVnOnt4= +github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -24,6 +26,7 @@ github.com/google/gopacket v1.1.16/go.mod h1:UCLx9mCmAwsVbn6qQl1WIEt2SO7Nd2fD0th github.com/google/gopacket v1.1.17 h1:rMrlX2ZY2UbvT+sdz3+6J+pp2z+msCq9MxTU6ymxbBY= github.com/google/gopacket v1.1.17/go.mod h1:UdDNZ1OO62aGYVnPhxT1U6aI7ukYtA/kB8vaU0diBUM= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/keegancsmith/rpc v1.1.0 h1:bXVRk3EzbtrEegTGKxNTc+St1lR7t/Z1PAO8misBnCc= @@ -37,27 +40,36 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.4/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mdlayher/raw v0.0.0-20181016155347-fa5ef3332ca9 h1:tOtO8DXiNGj9NshRKHWiZuGlSldPFzFCFYhNtsKTBCs= github.com/mdlayher/raw v0.0.0-20181016155347-fa5ef3332ca9/go.mod h1:rC/yE65s/DoHB6BzVOUBNYBGTg772JVytyAytffIZkY= github.com/mdlayher/raw v0.0.0-20190303161257-764d452d77af/go.mod h1:rC/yE65s/DoHB6BzVOUBNYBGTg772JVytyAytffIZkY= github.com/mdlayher/raw v0.0.0-20190419142535-64193704e472/go.mod h1:7EpbotpCmVZcu+KCX4g9WaRNuu11uyhiW7+Le1dKawg= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= +github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/viper v1.3.2 h1:VUFqw5KcqRf7i70GOzW7N+Q7+gxVBkSSqiXB12+JQ4M= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/stamblerre/gocode v0.0.0-20190327203809-810592086997 h1:LF81AGV63kJoxjmSgQPT8FARAMHeY46CYQ4TNoVDWHM= github.com/stamblerre/gocode v0.0.0-20190327203809-810592086997/go.mod h1:EM2T8YDoTCvGXbEpFHxarbpv7VE26QD1++Cb1Pbh7Gs= +github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/vishvananda/netlink v1.0.0 h1:bqNY2lgheFIu1meHUFSH3d7vG93AFyqg3oGbJCOJgSM= @@ -102,6 +114,7 @@ golang.org/x/sys v0.0.0-20190516014833-cab07311ab81/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190530182044-ad28b68e88f1 h1:R4dVlxdmKenVdMRS/tTspEpSTRWINYrHD8ySIU9yCIU= golang.org/x/sys v0.0.0-20190530182044-ad28b68e88f1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= @@ -113,6 +126,7 @@ golang.org/x/tools v0.0.0-20190530215528-75312fb06703/go.mod h1:/rFqwRUd4F7ZHNgw gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= honnef.co/go/tools v0.0.0-20190530170028-a1efa522b896 h1:6uyI/wyTvu/MnMY+zoFu7NvQcxWRSBGHvAORkTwZvyM= honnef.co/go/tools v0.0.0-20190530170028-a1efa522b896/go.mod h1:wtc9q0E9zm8PjdRMh29DPlTlCCHVzKDwnkT4GskQVzg= diff --git a/pkg/setups/base.go b/pkg/setups/base.go deleted file mode 100644 index f716ca6..0000000 --- a/pkg/setups/base.go +++ /dev/null @@ -1,29 +0,0 @@ -package setups - -import ( - "fmt" -) - -// RunSetup runs an appropriate testing setup -func RunSetup(setupName string, teardownFlag bool) { - // partially apply pickSetup with teardownFlag - pickPartial := func(s, t func()) { pickSetup(s, t, teardownFlag) } - switch setupName { - case "simple": - pickPartial(setupSimple, teardownSimple) - case "simpleClient": - pickPartial(setupClientSimple, teardownClientSimple) - default: - fmt.Println("Setup name" + setupName + " not found") - } -} - -func pickSetup(setup, teardown func(), teardownFlag bool) { - if teardownFlag { - fmt.Println("tearing down setup") - teardown() - } else { - fmt.Println("starting setup") - setup() - } -} diff --git a/pkg/setups/clientSimple.go b/pkg/setups/clientSimple.go deleted file mode 100644 index 5aca9ed..0000000 --- a/pkg/setups/clientSimple.go +++ /dev/null @@ -1,23 +0,0 @@ -package setups - -import ( - "log" - "net" - - "github.com/pwpon500/caplance/internal/client" -) - -func setupClientSimple() { - vip := net.ParseIP("10.0.0.50") - dataIP := net.ParseIP("10.0.0.2") - c := client.NewClient(vip, dataIP) - connectIP := net.ParseIP("10.0.0.1") - err := c.Start(connectIP) - if err != nil { - log.Panicln(err) - } -} - -func teardownClientSimple() { - -} diff --git a/pkg/setups/simple.go b/pkg/setups/simple.go deleted file mode 100644 index 5691145..0000000 --- a/pkg/setups/simple.go +++ /dev/null @@ -1,25 +0,0 @@ -package setups - -import ( - "net" - - "github.com/pwpon500/caplance/internal/balancer" -) - -func setupSimple() { - vip := net.ParseIP("10.0.0.50") - b, err := balancer.New(vip, net.ParseIP("10.0.0.1"), 53) - if err != nil { - panic(err) - } - // Add not currently supported - /*err = b.Add("b1", net.ParseIP("10.0.0.2")) - if err != nil { - panic(err) - }*/ - b.Start() -} - -func teardownSimple() { - -} diff --git a/test/configs/simple_config.yaml b/test/configs/simple_config.yaml new file mode 100644 index 0000000..90afde2 --- /dev/null +++ b/test/configs/simple_config.yaml @@ -0,0 +1,8 @@ +vip: 10.0.0.50 + +client: + dataIP: 10.0.0.2 + +server: + mngIP: 10.0.0.1 + backendCapacity: 53