K8s: Add path rewriter filter (#87456)

This commit is contained in:
Todd Treece 2024-05-08 11:08:43 -04:00 committed by GitHub
parent 04ce2d2f5a
commit f342217158
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 78 additions and 0 deletions

View File

@ -0,0 +1,31 @@
package filters
import (
"net/http"
"regexp"
)
type PathRewriter struct {
Pattern *regexp.Regexp
ReplaceFunc func([]string) string
}
func (r *PathRewriter) Rewrite(path string) (string, bool) {
matches := r.Pattern.FindStringSubmatch(path)
if matches == nil {
return path, false
}
return r.ReplaceFunc(r.Pattern.FindStringSubmatch(path)), true
}
func WithPathRewriters(handler http.Handler, rewriters []PathRewriter) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
for _, rewriter := range rewriters {
if newPath, ok := rewriter.Rewrite(req.URL.Path); ok {
req.URL.Path = newPath
break
}
}
handler.ServeHTTP(w, req)
})
}

View File

@ -0,0 +1,47 @@
package filters
import (
"net/http"
"net/http/httptest"
"regexp"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func Test_WithPathRewriters(t *testing.T) {
mockHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
_, err := w.Write([]byte(r.URL.Path))
require.NoError(t, err)
})
rewriters := []PathRewriter{
{
Pattern: regexp.MustCompile(`(/apis/scope.grafana.app/.*/query)(/.*)`),
ReplaceFunc: func(matches []string) string {
return matches[1]
},
},
}
handler := WithPathRewriters(mockHandler, rewriters)
t.Run("should rewrite path", func(t *testing.T) {
req, err := http.NewRequest("GET", "/apis/scope.grafana.app/namespaces/stack-1234/query/blah", nil)
assert.NoError(t, err)
rr := httptest.NewRecorder()
handler.ServeHTTP(rr, req)
assert.Equal(t, http.StatusOK, rr.Code)
assert.Equal(t, "/apis/scope.grafana.app/namespaces/stack-1234/query", rr.Body.String())
})
t.Run("should ignore requests that don't match", func(t *testing.T) {
req, err := http.NewRequest("GET", "/apis/scope.grafana.app/namespaces/stack-1234/scopes/1", nil)
assert.NoError(t, err)
rr := httptest.NewRecorder()
handler.ServeHTTP(rr, req)
assert.Equal(t, http.StatusOK, rr.Code)
assert.Equal(t, "/apis/scope.grafana.app/namespaces/stack-1234/scopes/1", rr.Body.String())
})
}