From 7b328d88cf2ecdbcffe0906a402d3279efdadfe6 Mon Sep 17 00:00:00 2001 From: Flynn Date: Thu, 2 May 2024 08:08:34 -0400 Subject: [PATCH 1/2] Support setting USER_HEADER_NAME to tell Faces which header to get a username from Signed-off-by: Flynn --- assets/html/index.html | 2 +- pkg/faces/baseserver.go | 5 ++++- pkg/faces/faceserver.go | 6 +++--- pkg/faces/guiserver.go | 14 ++++++++++---- 4 files changed, 18 insertions(+), 9 deletions(-) diff --git a/assets/html/index.html b/assets/html/index.html index 710f123..1f3ca29 100644 --- a/assets/html/index.html +++ b/assets/html/index.html @@ -754,7 +754,7 @@

Faces

let now = new Date().toISOString() xhr.open("GET", `${this.fetchURL}?row=${this.row}&col=${this.col}&now=${now}`); xhr.setRequestHeader("Cache-Control", "no-cache, no-store, max-age=0"); - xhr.setRequestHeader("X-Faces-User", this.sw.userControl.user); + xhr.setRequestHeader("%%{user_header}", this.sw.userControl.user); // We must send credentials... xhr.withCredentials = true diff --git a/pkg/faces/baseserver.go b/pkg/faces/baseserver.go index fe48b46..483a5ee 100644 --- a/pkg/faces/baseserver.go +++ b/pkg/faces/baseserver.go @@ -90,6 +90,7 @@ type BaseServer struct { server *http.ServeMux preHook Hook postHook Hook + userHeaderName string } func NewBaseServer(serverName string) *BaseServer { @@ -153,6 +154,7 @@ func (srv *BaseServer) SetupFromEnvironment() { srv.RegisterCustom("/rl", srv.rlGetHandler) + srv.userHeaderName = utils.StringFromEnv("USER_HEADER_NAME", "X-Faces-User") srv.hostIP = utils.StringFromEnv("HOST_IP", utils.StringFromEnv("HOSTNAME", "unknown")) delayBucketsStr := utils.StringFromEnv("DELAY_BUCKETS", "") @@ -188,6 +190,7 @@ func (srv *BaseServer) SetupFromEnvironment() { fmt.Printf("%s %s: latch_fraction %d\n", time.Now().Format(time.RFC3339), srv.Name, srv.latchFraction) fmt.Printf("%s %s: debug_enabled %v\n", time.Now().Format(time.RFC3339), srv.Name, srv.debugEnabled) fmt.Printf("%s %s: max_rate %f\n", time.Now().Format(time.RFC3339), srv.Name, srv.maxRate) + fmt.Printf("%s %s: userHeaderName %v\n", time.Now().Format(time.RFC3339), srv.Name, srv.userHeaderName) } func (srv *BaseServer) ListenAndServe(port string) { @@ -430,7 +433,7 @@ func (srv *BaseServer) standardHeaders(w http.ResponseWriter, r *http.Request, s } w.Header().Set("Content-Type", contentType) - w.Header().Set("X-Faces-User", r.Header.Get("x-faces-user")) + w.Header().Set(srv.userHeaderName, r.Header.Get(srv.userHeaderName)) w.Header().Set("User-Agent", r.Header.Get("User-Agent")) w.Header().Set("X-Faces-Pod", srv.hostIP) w.WriteHeader(statusCode) diff --git a/pkg/faces/faceserver.go b/pkg/faces/faceserver.go index 8980e5f..4207de8 100644 --- a/pkg/faces/faceserver.go +++ b/pkg/faces/faceserver.go @@ -86,7 +86,7 @@ func (srv *FaceServer) makeRequest(user string, userAgent string, service string } if !failed { - req.Header.Set("X-Faces-User", user) + req.Header.Set(srv.userHeaderName, user) req.Header.Set("User-Agent", userAgent) response, err = http.DefaultClient.Do(req) @@ -190,7 +190,7 @@ func (srv *FaceServer) faceGetHandler(r *http.Request, rstat *BaseRequestStatus) smiley, smileyOK = Smileys.Lookup(Defaults["smiley-ratelimit"]) color = Colors.Lookup(Defaults["color-ratelimit"]) } else { - user := r.Header.Get("X-Faces-User") + user := r.Header.Get(srv.userHeaderName) if user == "" { user = "unknown" @@ -224,7 +224,7 @@ func (srv *FaceServer) faceGetHandler(r *http.Request, rstat *BaseRequestStatus) if srv.debugEnabled { fmt.Printf("%s %s: mapped smiley %d to %s (%s, %v)\n", - time.Now().Format(time.RFC3339), srv.Name, smileyResp.statusCode, mapped, smiley, smileyOK) + time.Now().Format(time.RFC3339), srv.Name, smileyResp.statusCode, mapped, smiley, smileyOK) } } else { smiley = smileyResp.data diff --git a/pkg/faces/guiserver.go b/pkg/faces/guiserver.go index e1dfa03..273bb77 100644 --- a/pkg/faces/guiserver.go +++ b/pkg/faces/guiserver.go @@ -71,8 +71,10 @@ func (srv *GUIServer) guiGetHandler(w http.ResponseWriter, r *http.Request) { start := time.Now() fmt.Printf("%s %s: GET %s\n", time.Now().Format(time.RFC3339), srv.Name, r.URL.Path) + fmt.Printf(" userHeaderName: %s\n", srv.userHeaderName) + fmt.Printf(" headers: %s\n", r.Header) - user := r.Header.Get("x-faces-user") + user := r.Header.Get(srv.userHeaderName) if user == "" { user = "unknown" } @@ -81,6 +83,9 @@ func (srv *GUIServer) guiGetHandler(w http.ResponseWriter, r *http.Request) { userAgent = "unknown" } + fmt.Printf(" user: %s\n", user) + fmt.Printf(" userAgent: %s\n", userAgent) + podID := srv.hostIP rcode := http.StatusNotFound rtext := fmt.Sprintf("%s not found", r.URL.Path) @@ -92,7 +97,7 @@ func (srv *GUIServer) guiGetHandler(w http.ResponseWriter, r *http.Request) { latencyMs := end.Sub(start).Milliseconds() w.Header().Set("Content-Type", "text/plain") - w.Header().Set("X-Faces-User", user) + w.Header().Set(srv.userHeaderName, user) w.Header().Set("X-Faces-User-Agent", userAgent) w.Header().Set("X-Faces-Latency", strconv.FormatInt(latencyMs, 10)) w.Header().Set("X-Faces-Pod", podID) @@ -118,6 +123,7 @@ func (srv *GUIServer) guiGetHandler(w http.ResponseWriter, r *http.Request) { rtext = strings.ReplaceAll(rtext, "%%{hide_key}", fmt.Sprintf("%v", srv.hideKey)) rtext = strings.ReplaceAll(rtext, "%%{show_pods}", fmt.Sprintf("%v", srv.showPods)) rtext = strings.ReplaceAll(rtext, "%%{user}", user) + rtext = strings.ReplaceAll(rtext, "%%{user_header}", fmt.Sprintf("%v", srv.userHeaderName)) rtext = strings.ReplaceAll(rtext, "%%{user_agent}", userAgent) } } else if strings.HasPrefix(r.URL.Path, "/face/") { @@ -127,7 +133,7 @@ func (srv *GUIServer) guiGetHandler(w http.ResponseWriter, r *http.Request) { reqStart := time.Now() url := fmt.Sprintf("http://face/%s", r.URL.Path[6:]) - user := r.Header.Get("x-faces-user") + user := r.Header.Get(srv.userHeaderName) if user == "" { user = "unknown" } @@ -202,7 +208,7 @@ func (srv *GUIServer) guiGetHandler(w http.ResponseWriter, r *http.Request) { latencyMs := end.Sub(start).Milliseconds() w.Header().Set("Content-Type", rtype) - w.Header().Set("X-Faces-User", user) + w.Header().Set(srv.userHeaderName, user) w.Header().Set("X-Faces-User-Agent", userAgent) w.Header().Set("X-Faces-Latency", strconv.FormatInt(latencyMs, 10)) w.Header().Set("X-Faces-Pod", podID) From 1324f43d169132b5dead6d6465fc1e12e5da550e Mon Sep 17 00:00:00 2001 From: Flynn Date: Thu, 2 May 2024 08:09:36 -0400 Subject: [PATCH 2/2] Fix the chart so that setting the error fraction for individual backend elements works. Signed-off-by: Flynn --- faces-chart/templates/_helpers.tpl | 5 ++-- faces-chart/values.yaml | 48 +++++++++++++++--------------- 2 files changed, 27 insertions(+), 26 deletions(-) diff --git a/faces-chart/templates/_helpers.tpl b/faces-chart/templates/_helpers.tpl index bc5b1db..3089f4b 100644 --- a/faces-chart/templates/_helpers.tpl +++ b/faces-chart/templates/_helpers.tpl @@ -55,8 +55,9 @@ {{- define "partials.select-errorFraction" -}} {{ $fraction := "" }} - {{- if .source.errorFraction -}} - {{- $fraction = .source.errorFraction -}} + {{ $srcFraction := .source.errorFraction }} + {{- if or ($srcFraction) (eq $srcFraction 0) -}} + {{- $fraction = $srcFraction -}} {{- else if (and .default .default.errorFraction) -}} {{- $fraction = .default.errorFraction -}} {{- end -}} diff --git a/faces-chart/values.yaml b/faces-chart/values.yaml index feeeda0..f589cbd 100644 --- a/faces-chart/values.yaml +++ b/faces-chart/values.yaml @@ -33,39 +33,39 @@ backend: delayBuckets: "0,5,10,15,20,50,200,500,1500" smiley: - image: "" # If set, overrides the imageName/imageTag pair - imageName: "" # If not set, uses backend.imageName - imageTag: "" # If not set, uses backend.imageTag - imagePullPolicy: "" # If not set, uses backend.imagePullPolicy - errorFraction: "" # If not set, uses backend.errorFraction - delayBuckets: "" # If not set, uses backend.delayBuckets smiley: "" # Override if desired + # image: "" # If set, overrides the imageName/imageTag pair + # imageName: "" # If not set, uses backend.imageName + # imageTag: "" # If not set, uses backend.imageTag + # imagePullPolicy: "" # If not set, uses backend.imagePullPolicy + # errorFraction: "" # If not set, uses backend.errorFraction + # delayBuckets: "" # If not set, uses backend.delayBuckets smiley2: enabled: False # If set to True, enables the second smiley workload - image: "" # If set, overrides the imageName/imageTag pair - imageName: "" # If not set, uses backend.imageName - imageTag: "" # If not set, uses backend.imageTag - imagePullPolicy: "" # If not set, uses backend.imagePullPolicy - errorFraction: "" # If not set, uses backend.errorFraction - delayBuckets: "" # If not set, uses backend.delayBuckets smiley: "HeartEyes" # Override if desired + # image: "" # If set, overrides the imageName/imageTag pair + # imageName: "" # If not set, uses backend.imageName + # imageTag: "" # If not set, uses backend.imageTag + # imagePullPolicy: "" # If not set, uses backend.imagePullPolicy + # errorFraction: "" # If not set, uses backend.errorFraction + # delayBuckets: "" # If not set, uses backend.delayBuckets color: - image: "" # If set, overrides the imageName/imageTag pair - imageName: "" # If not set, uses backend.imageName - imageTag: "" # If not set, uses backend.imageTag - imagePullPolicy: "" # If not set, uses backend.imagePullPolicy - errorFraction: "" # If not set, uses backend.errorFraction - delayBuckets: "" # If not set, uses backend.delayBuckets color: "" # Override if desired, defaults to colorblind-friendly light blue from the Tol palette + # image: "" # If set, overrides the imageName/imageTag pair + # imageName: "" # If not set, uses backend.imageName + # imageTag: "" # If not set, uses backend.imageTag + # imagePullPolicy: "" # If not set, uses backend.imagePullPolicy + # errorFraction: "" # If not set, uses backend.errorFraction + # delayBuckets: "" # If not set, uses backend.delayBuckets color2: enabled: False # If set to True, enables the second color workload - image: "" # If set, overrides the imageName/imageTag pair - imageName: "" # If not set, uses backend.imageName - imageTag: "" # If not set, uses backend.imageTag - imagePullPolicy: "" # If not set, uses backend.imagePullPolicy - errorFraction: "" # If not set, uses backend.errorFraction - delayBuckets: "" # If not set, uses backend.delayBuckets color: "green" # Override if desired, defaults to colorblind-friendly green from the Tol palette + # image: "" # If set, overrides the imageName/imageTag pair + # imageName: "" # If not set, uses backend.imageName + # imageTag: "" # If not set, uses backend.imageTag + # imagePullPolicy: "" # If not set, uses backend.imagePullPolicy + # errorFraction: "" # If not set, uses backend.errorFraction + # delayBuckets: "" # If not set, uses backend.delayBuckets