diff --git a/README.md b/README.md index 137d048d..9b0dc473 100644 --- a/README.md +++ b/README.md @@ -287,8 +287,12 @@ Toxiproxy. For large application we recommend storing the Toxiproxy configurations in a separate configuration file. We use `config/toxiproxy.json`. This file can be -passed to the server using the `-config` option, or loaded by the application +passed to the server using the `-configFile` option, or loaded by the application to use with the `populate` function. +Alternatively you can pass a json string with the `-configJson` option to populate +these configurations. This is specially useful when running Toxiproxy as a docker container, e.g.: + +```docker run -it shopify/toxiproxy -configJson '[{"name": "redis","listen": "0.0.0.0:9092","upstream": "redis:6379"}]'``` Use ports outside the ephemeral port range to avoid random port conflicts. It's `32,768` to `61,000` on Linux by default, see diff --git a/api.go b/api.go index 02edd9aa..014c32f2 100644 --- a/api.go +++ b/api.go @@ -1,8 +1,10 @@ package toxiproxy import ( + "bytes" "encoding/json" "fmt" + "io" "log" "net" "net/http" @@ -24,7 +26,7 @@ func NewServer() *ApiServer { } } -func (server *ApiServer) PopulateConfig(filename string) { +func (server *ApiServer) PopulateConfigFromFile(filename string) { file, err := os.Open(filename) if err != nil { logrus.WithFields(logrus.Fields{ @@ -32,18 +34,26 @@ func (server *ApiServer) PopulateConfig(filename string) { "error": err, }).Error("Error reading config file") } else { - proxies, err := server.Collection.PopulateJson(file) - if err != nil { - logrus.WithFields(logrus.Fields{ - "config": filename, - "error": err, - }).Error("Failed to populate proxies from file") - } else { - logrus.WithFields(logrus.Fields{ - "config": filename, - "proxies": len(proxies), - }).Info("Populated proxies from file") - } + server.populateConfig(file) + } +} + +func (server *ApiServer) PopulateConfigFromJsonString(json string) { + var data = bytes.NewReader([]byte(json)) + + server.populateConfig(data) +} + +func (server *ApiServer) populateConfig(data io.Reader) { + proxies, err := server.Collection.PopulateJson(data) + if err != nil { + logrus.WithFields(logrus.Fields{ + "error": err, + }).Error("Failed to populate proxies from file") + } else { + logrus.WithFields(logrus.Fields{ + "proxies": len(proxies), + }).Info("Populated proxies from file") } } diff --git a/api_test.go b/api_test.go index 488f3d1e..306c49bf 100644 --- a/api_test.go +++ b/api_test.go @@ -323,7 +323,7 @@ func TestPopulateProxyWithBadDataShouldReturnError(t *testing.T) { for _, p := range proxies { if p.Name == "two" || p.Name == "three" { - t.Fatalf("Proxy %s exists, populate did not fail correctly.") + t.Fatalf("Proxy %s exists, populate did not fail correctly.", p.Name) } } }) diff --git a/cmd/toxiproxy.go b/cmd/toxiproxy.go index 5fb5b8e0..bc734923 100644 --- a/cmd/toxiproxy.go +++ b/cmd/toxiproxy.go @@ -9,16 +9,19 @@ import ( "time" "github.com/Shopify/toxiproxy" + "github.com/sirupsen/logrus" ) var host string var port string -var config string +var configJson string +var configFile string func init() { flag.StringVar(&host, "host", "localhost", "Host for toxiproxy's API to listen on") flag.StringVar(&port, "port", "8474", "Port for toxiproxy's API to listen on") - flag.StringVar(&config, "config", "", "JSON file containing proxies to create on startup") + flag.StringVar(&configFile, "configFile", "", "JSON file containing proxies to create on startup") + flag.StringVar(&configJson, "configJson", "", "JSON literal containing proxies to create on startup") seed := flag.Int64("seed", time.Now().UTC().UnixNano(), "Seed for randomizing toxics with") flag.Parse() rand.Seed(*seed) @@ -26,8 +29,19 @@ func init() { func main() { server := toxiproxy.NewServer() - if len(config) > 0 { - server.PopulateConfig(config) + + if len(configFile) > 0 && len(configJson) > 0 { + logrus.WithFields(logrus.Fields{ + "configFile": configFile, + "configJson": configJson, + }).Error("configFile and configJson are mutually exclusive") + } else { + if len(configFile) > 0 { + server.PopulateConfigFromFile(configFile) + } + if len(configJson) > 0 { + server.PopulateConfigFromJsonString(configJson) + } } // Handle SIGTERM to exit cleanly