Permalink
Browse files

Add -config option for toxiproxy startup

  • Loading branch information...
xthexder committed Dec 7, 2016
1 parent 8e40aad commit 46df58de01ccec4756ef3495aa1190eb1ea4dc49
Showing with 93 additions and 50 deletions.
  1. +18 −49 api.go
  2. +26 −0 cmd/toxiproxy.go
  3. +49 −1 proxy_collection.go
View
67 api.go
@@ -132,65 +132,27 @@ func (server *ApiServer) ProxyCreate(response http.ResponseWriter, request *http
}
func (server *ApiServer) Populate(response http.ResponseWriter, request *http.Request) {
- input := []struct {
- Proxy
- Enabled *bool `json:"enabled"` // Overrides Proxy field to make field nullable
- }{}
+ proxies, err := server.Collection.PopulateJson(request.Body)
- err := json.NewDecoder(request.Body).Decode(&input)
- if apiError(response, joinError(err, ErrBadRequestBody)) {
- return
- }
-
- // Check for valid input before creating any proxies
- t := true
- for i, p := range input {
- if len(p.Name) < 1 {
- apiError(response, joinError(fmt.Errorf("name at proxy %d", i+1), ErrMissingField))
- return
- }
- if len(p.Upstream) < 1 {
- apiError(response, joinError(fmt.Errorf("upstream at proxy %d", i+1), ErrMissingField))
- return
- }
- if p.Enabled == nil {
- input[i].Enabled = &t
- }
- }
-
- proxies := make([]proxyToxics, 0, len(input))
-
- responseCode := http.StatusCreated
- var apiErr *ApiError
- for _, p := range input {
- proxy := NewProxy()
- proxy.Name = p.Name
- proxy.Listen = p.Listen
- proxy.Upstream = p.Upstream
-
- err = server.Collection.AddOrReplace(proxy, *p.Enabled)
- if err != nil {
- var ok bool
- apiErr, ok = err.(*ApiError)
- if !ok {
- logrus.Warn("Error did not include status code: ", err)
- apiErr = &ApiError{err.Error(), http.StatusInternalServerError}
- }
- responseCode = apiErr.StatusCode
- break
- }
-
- proxies = append(proxies, proxyWithToxics(proxy))
+ apiErr, ok := err.(*ApiError)
+ if !ok && err != nil {
+ logrus.Warn("Error did not include status code: ", err)
+ apiErr = &ApiError{err.Error(), http.StatusInternalServerError}
}
data, err := json.Marshal(struct {
*ApiError `json:",omitempty"`
Proxies []proxyToxics `json:"proxies"`
- }{apiErr, proxies})
+ }{apiErr, proxiesWithToxics(proxies)})
if apiError(response, err) {
return
}
+ responseCode := http.StatusCreated
+ if apiErr != nil {
+ responseCode = apiErr.StatusCode
+ }
+
response.Header().Set("Content-Type", "application/json")
response.WriteHeader(responseCode)
_, err = response.Write(data)
@@ -453,3 +415,10 @@ func proxyWithToxics(proxy *Proxy) (result proxyToxics) {
result.Toxics = proxy.Toxics.GetToxicArray()
return
}
+
+func proxiesWithToxics(proxies []*Proxy) (result []proxyToxics) {
+ for _, proxy := range proxies {
+ result = append(result, proxyWithToxics(proxy))
+ }
+ return
+}
View
@@ -3,23 +3,49 @@ package main
import (
"flag"
"math/rand"
+ "os"
"time"
"github.com/Shopify/toxiproxy"
+ "github.com/Sirupsen/logrus"
)
var host string
var port string
+var config 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")
seed := flag.Int64("seed", time.Now().UTC().UnixNano(), "Seed for randomizing toxics with")
flag.Parse()
rand.Seed(*seed)
}
func main() {
server := toxiproxy.NewServer()
+ if len(config) > 0 {
+ file, err := os.Open(config)
+ if err != nil {
+ logrus.WithFields(logrus.Fields{
+ "config": config,
+ "error": err,
+ }).Error("Error reading config file")
+ } else {
+ proxies, err := server.Collection.PopulateJson(file)
+ if err != nil {
+ logrus.WithFields(logrus.Fields{
+ "config": config,
+ "error": err,
+ }).Error("Failed to populate proxies from file")
+ } else {
+ logrus.WithFields(logrus.Fields{
+ "config": config,
+ "proxies": len(proxies),
+ }).Info("Populated proxies from file")
+ }
+ }
+ }
server.Listen(host, port)
}
View
@@ -1,6 +1,11 @@
package toxiproxy
-import "sync"
+import (
+ "encoding/json"
+ "fmt"
+ "io"
+ "sync"
+)
// ProxyCollection is a collection of proxies. It's the interface for anything
// to add and remove proxies from the toxiproxy instance. It's responsibilty is
@@ -61,6 +66,49 @@ func (collection *ProxyCollection) AddOrReplace(proxy *Proxy, start bool) error
return nil
}
+func (collection *ProxyCollection) PopulateJson(data io.Reader) ([]*Proxy, error) {
+ input := []struct {
+ Proxy
+ Enabled *bool `json:"enabled"` // Overrides Proxy field to make field nullable
+ }{}
+
+ err := json.NewDecoder(data).Decode(&input)
+ if err != nil {
+ return nil, joinError(err, ErrBadRequestBody)
+ }
+
+ // Check for valid input before creating any proxies
+ t := true
+ for i, p := range input {
+ if len(p.Name) < 1 {
+ return nil, joinError(fmt.Errorf("name at proxy %d", i+1), ErrMissingField)
+ }
+ if len(p.Upstream) < 1 {
+ return nil, joinError(fmt.Errorf("upstream at proxy %d", i+1), ErrMissingField)
+ }
+ if p.Enabled == nil {
+ input[i].Enabled = &t
+ }
+ }
+
+ proxies := make([]*Proxy, 0, len(input))
+
+ for _, p := range input {
+ proxy := NewProxy()
+ proxy.Name = p.Name
+ proxy.Listen = p.Listen
+ proxy.Upstream = p.Upstream
+
+ err = collection.AddOrReplace(proxy, *p.Enabled)
+ if err != nil {
+ break
+ }
+
+ proxies = append(proxies, proxy)
+ }
+ return proxies, err
+}
+
func (collection *ProxyCollection) Proxies() map[string]*Proxy {
collection.RLock()
defer collection.RUnlock()

0 comments on commit 46df58d

Please sign in to comment.