From dff330a6e5eb43b094d76fbcd781e335753cb3a2 Mon Sep 17 00:00:00 2001 From: Jacob Bednarz Date: Wed, 11 Oct 2017 09:25:05 +1100 Subject: [PATCH 1/7] Add test coverage for dashboard route --- api_test.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/api_test.go b/api_test.go index 488f3d1e..b48ea3e1 100644 --- a/api_test.go +++ b/api_test.go @@ -36,6 +36,19 @@ func WithServer(t *testing.T, f func(string)) { f("http://localhost:8475") } +func TestDashboardIsAccessible(t *testing.T) { + WithServer(t, func(addr string) { + client := http.Client{} + + req, _ := http.NewRequest("GET", "http://localhost:8475/dashboard", nil) + resp, _ := client.Do(req) + + if resp.StatusCode != 200 { + t.Fatal("Dashboard is not accessible at /dashboard") + } + }) +} + func TestBrowserGets403(t *testing.T) { WithServer(t, func(addr string) { client := http.Client{} From bf8ba98181fbef329b65d4d114d77adc38c468ee Mon Sep 17 00:00:00 2001 From: Jacob Bednarz Date: Wed, 11 Oct 2017 08:03:21 +1100 Subject: [PATCH 2/7] Expose `/dashboard` route Updates the router to handle `/dashboard` which will house the UI for toxiproxy. --- api.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/api.go b/api.go index 35be6df1..96bcff34 100644 --- a/api.go +++ b/api.go @@ -74,6 +74,8 @@ func (server *ApiServer) Listen(host string, port string) { r.HandleFunc("/version", server.Version).Methods("GET") + r.HandleFunc("/dashboard", server.Dashboard).Methods("GET") + http.Handle("/", StopBrowsersMiddleware(r)) logrus.WithFields(logrus.Fields{ @@ -389,6 +391,14 @@ func (server *ApiServer) Version(response http.ResponseWriter, request *http.Req } } +func (server *ApiServer) Dashboard(response http.ResponseWriter, request *http.Request) { + response.Header().Set("Content-Type", "text/plain") + _, err := response.Write([]byte(":wave:")) + if err != nil { + logrus.Warn("Version: Failed to write response to client", err) + } +} + type ApiError struct { Message string `json:"error"` StatusCode int `json:"status"` From 62d0bcb5701b1edaa7eaaf3cd2bd484f31076e5f Mon Sep 17 00:00:00 2001 From: Jacob Bednarz Date: Wed, 11 Oct 2017 08:04:09 +1100 Subject: [PATCH 3/7] Bypass `StopBrowsersMiddleware` checks for the dashboard --- api.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api.go b/api.go index 96bcff34..1f5f078e 100644 --- a/api.go +++ b/api.go @@ -49,7 +49,7 @@ func (server *ApiServer) PopulateConfig(filename string) { func StopBrowsersMiddleware(h http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if strings.HasPrefix(r.UserAgent(), "Mozilla/") { + if strings.HasPrefix(r.UserAgent(), "Mozilla/") && r.URL.Path != "/dashboard" { http.Error(w, "User agent not allowed", 403) } else { h.ServeHTTP(w, r) From 0a591a0794dffa9b7c4a63c0185ed038d859f319 Mon Sep 17 00:00:00 2001 From: Jacob Bednarz Date: Sat, 14 Oct 2017 09:52:02 +1100 Subject: [PATCH 4/7] Verrrry basic UI for displaying all proxies It's not pretty but it works. --- api.go | 8 +++----- templates/dashboard.tmpl | 10 ++++++++++ 2 files changed, 13 insertions(+), 5 deletions(-) create mode 100644 templates/dashboard.tmpl diff --git a/api.go b/api.go index 1f5f078e..8bc32949 100644 --- a/api.go +++ b/api.go @@ -2,6 +2,7 @@ package toxiproxy import ( "encoding/json" + "html/template" "fmt" "log" "net" @@ -392,11 +393,8 @@ func (server *ApiServer) Version(response http.ResponseWriter, request *http.Req } func (server *ApiServer) Dashboard(response http.ResponseWriter, request *http.Request) { - response.Header().Set("Content-Type", "text/plain") - _, err := response.Write([]byte(":wave:")) - if err != nil { - logrus.Warn("Version: Failed to write response to client", err) - } + tmpl := template.Must(template.ParseFiles("templates/dashboard.tmpl")) + tmpl.Execute(response, server.Collection.Proxies()) } type ApiError struct { diff --git a/templates/dashboard.tmpl b/templates/dashboard.tmpl new file mode 100644 index 00000000..3a290a5d --- /dev/null +++ b/templates/dashboard.tmpl @@ -0,0 +1,10 @@ + + {{ range . }} + + + + + + + {{ end }} +
{{ .Name }}listen: {{ .Listen }}upstream: {{ .Upstream }}enabled:
From 56ebb3fde333ddc9cd62ce7e191588274314db36 Mon Sep 17 00:00:00 2001 From: Jacob Bednarz Date: Sat, 14 Oct 2017 11:30:32 +1100 Subject: [PATCH 5/7] Swap to using `proxyWithToxics` for Toxics data Instead of trying to map this out myself, just reuse a combinaton of the `server.Collection.Proxies()` with `proxyWithToxics` to iterate over the available proxies and their toxics. --- api.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/api.go b/api.go index 8bc32949..9252200d 100644 --- a/api.go +++ b/api.go @@ -393,8 +393,13 @@ func (server *ApiServer) Version(response http.ResponseWriter, request *http.Req } func (server *ApiServer) Dashboard(response http.ResponseWriter, request *http.Request) { + var dashboardData []proxyToxics + for _, proxyName := range server.Collection.Proxies() { + dashboardData = append(dashboardData, proxyWithToxics(proxyName)) + } + tmpl := template.Must(template.ParseFiles("templates/dashboard.tmpl")) - tmpl.Execute(response, server.Collection.Proxies()) + tmpl.Execute(response, dashboardData) } type ApiError struct { From 5788b5c7f7f53b4240300831c91994e78e52707c Mon Sep 17 00:00:00 2001 From: Jacob Bednarz Date: Sat, 14 Oct 2017 11:30:49 +1100 Subject: [PATCH 6/7] Fancy up the dashboard with all the available keys --- templates/dashboard.tmpl | 53 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 4 deletions(-) diff --git a/templates/dashboard.tmpl b/templates/dashboard.tmpl index 3a290a5d..4bcc41f1 100644 --- a/templates/dashboard.tmpl +++ b/templates/dashboard.tmpl @@ -1,10 +1,55 @@ {{ range . }} - - - - + + {{ range .Toxics }} + + + {{ end }} {{ end }} +
{{ .Name }}listen: {{ .Listen }}upstream: {{ .Upstream }}enabled: {{ .Proxy.Name }} listen: {{ .Proxy.Listen }} upstream: {{ .Proxy.Upstream }} + Enabled?
+ name: {{ .Name }} + + type: {{ .Type }} + + stream: {{ .Stream }} + + toxicity: {{ .Toxicity }} + + direction: {{ .Direction }} + + index: {{ .Index }} + + buffer: {{ .BufferSize }} + + + {{ if eq .Type "latency" }} + jitter: {{ .Toxic.Jitter }}ms
+ latency: {{ .Toxic.Latency}}ms + {{ end }} + + {{ if eq .Type "bandwidth" }} + rate: {{ .Toxic.Rate }}KB/s + {{ end }} + + {{ if eq .Type "limit_data" }} + bytes: {{ .Toxic.Bytes }} bytes + {{ end }} + + {{ if eq .Type "slicer" }} + average size: {{ .Toxic.AverageSize }} bytes
+ size variation: {{ .Toxic.SizeVariation }} bytes
+ delay: {{ .Toxic.Delay }} microseconds + {{ end }} + + {{ if eq .Type "slow_close" }} + delay: {{ .Toxic.Delay }}ms + {{ end }} + + {{ if eq .Type "timeout" }} + timeout: {{ .Toxic.Timeout }}ms + {{ end }} +
From f14b8e3383ac4c10865960383ee0550066142a6b Mon Sep 17 00:00:00 2001 From: Jacob Bednarz Date: Mon, 23 Oct 2017 16:20:29 +1100 Subject: [PATCH 7/7] Add the values into text inputs --- templates/dashboard.tmpl | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/templates/dashboard.tmpl b/templates/dashboard.tmpl index 4bcc41f1..29fdbd39 100644 --- a/templates/dashboard.tmpl +++ b/templates/dashboard.tmpl @@ -23,30 +23,30 @@ {{ if eq .Type "latency" }} - jitter: {{ .Toxic.Jitter }}ms
- latency: {{ .Toxic.Latency}}ms + jitter: ms
+ latency: ms {{ end }} {{ if eq .Type "bandwidth" }} - rate: {{ .Toxic.Rate }}KB/s + rate: KB/s {{ end }} {{ if eq .Type "limit_data" }} - bytes: {{ .Toxic.Bytes }} bytes + bytes: bytes {{ end }} {{ if eq .Type "slicer" }} - average size: {{ .Toxic.AverageSize }} bytes
- size variation: {{ .Toxic.SizeVariation }} bytes
- delay: {{ .Toxic.Delay }} microseconds + average size: bytes
+ size variation: bytes
+ delay: microseconds {{ end }} {{ if eq .Type "slow_close" }} - delay: {{ .Toxic.Delay }}ms + delay: ms {{ end }} {{ if eq .Type "timeout" }} - timeout: {{ .Toxic.Timeout }}ms + timeout: ms {{ end }} {{ end }}