Skip to content

Commit

Permalink
Add support for configurable monitoring (#11)
Browse files Browse the repository at this point in the history
  • Loading branch information
packruler committed Jun 19, 2022
1 parent 11e7460 commit b57f614
Show file tree
Hide file tree
Showing 21 changed files with 952 additions and 342 deletions.
3 changes: 3 additions & 0 deletions .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,8 @@ RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
USER vscode
RUN go install mvdan.cc/gofumpt@latest

ENV YAEGI_VERSION="v0.9.20"
RUN curl -sfL https://raw.githubusercontent.com/traefik/yaegi/master/install.sh | bash -s -- -b $(go env GOPATH)/bin ${YAEGI_VERSION}

# [Optional] Uncomment this line to install global node packages.
# RUN su vscode -c "source /usr/local/share/nvm/nvm.sh && npm install -g <your-package-here>" 2>&1
4 changes: 3 additions & 1 deletion .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,7 @@
"remoteUser": "vscode",
"features": {
"git": "latest"
}
},
"workspaceMount": "source=${localWorkspaceFolder},target=/go/src/github.com/${localWorkspaceFolderBasename},type=bind,consistency=cached",
"workspaceFolder": "/go/src/github.com/${localWorkspaceFolderBasename}"
}
1 change: 1 addition & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ on:
push:
branches:
- master
- plugin-utils
tags:
- v*
pull_request:
Expand Down
4 changes: 4 additions & 0 deletions .golangci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,7 @@ issues:
- goconst
- funlen
- godot
- lll
- path: config.go
linters:
- lll
4 changes: 4 additions & 0 deletions .traefik.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,7 @@ testData:
rewrites:
- regex: "bar"
replacement: "foo"
monitor:
types:
- text/html
methods: ["GET"]
19 changes: 16 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ experimental:
plugins:
rewrite-body:
moduleName: "github.com/packruler/rewrite-body"
version: "v1.0.1"
version: "v1.1.0"
```
### Dynamic
Expand Down Expand Up @@ -77,8 +77,21 @@ http:
replacement: "bar"

# logLevel is optional, defaults to Info level.
# Available logLevels: (Trace: -1, Debug: 1, Info: 2, Warning: 3, Error: 4)
logLevel: 2
# Available logLevels: (Trace: -2, Debug: -1, Info: 0, Warning: 1, Error: 2)
logLevel: 0

# monitoring is optional, defaults to below configuration
# monitoring configuration limits the HTTP queries that are checked for regex replacement.
monitoring:
# methods is a string list. Options are standard HTTP Methods. Entries MUST be ALL CAPS
# For a list of options: https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods
methods:
- GET
# types is a string list. Options are HTTP Content Types. Entries should match standard formatting
# For a list of options: https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types
# Wildcards(*) are not supported!
types:
- text/html
services:
my-service:
loadBalancer:
Expand Down
10 changes: 10 additions & 0 deletions compressutil/compressions.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package compressutil

const (
// Gzip compression algorithm string.
Gzip string = "gzip"
// Deflate compression algorithm string.
Deflate string = "deflate"
// Identity compression algorithm string.
Identity string = "identity"
)
15 changes: 9 additions & 6 deletions compressutil/compressutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,24 @@ type ReaderError struct {
}

// Decode data in a bytes.Reader based on supplied encoding.
func Decode(byteReader *bytes.Buffer, encoding string) (data []byte, err error) {
func Decode(byteReader *bytes.Buffer, encoding string) ([]byte, error) {
reader, err := getRawReader(byteReader, encoding)
if err != nil {
return nil, &ReaderError{cause: err}
return nil, &ReaderError{
error: err,
cause: err,
}
}

return io.ReadAll(reader)
}

func getRawReader(byteReader *bytes.Buffer, encoding string) (io.Reader, error) {
switch encoding {
case "gzip":
case Gzip:
return gzip.NewReader(byteReader)

case "deflate":
case Deflate:
return flate.NewReader(byteReader), nil

default:
Expand All @@ -42,10 +45,10 @@ func getRawReader(byteReader *bytes.Buffer, encoding string) (io.Reader, error)
// Encode data in a []byte based on supplied encoding.
func Encode(data []byte, encoding string) ([]byte, error) {
switch encoding {
case "gzip":
case Gzip:
return compressWithGzip(data)

case "deflate":
case Deflate:
return compressWithZlib(data)

default:
Expand Down
12 changes: 6 additions & 6 deletions compressutil/compressutil_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,21 +33,21 @@ func TestEncode(t *testing.T) {
desc: "should support identity",
input: normalBytes,
expected: normalBytes,
encoding: "identity",
encoding: compressutil.Identity,
shouldMatch: true,
},
{
desc: "should support gzip",
input: normalBytes,
expected: gzippedBytes,
encoding: "gzip",
encoding: compressutil.Gzip,
shouldMatch: false,
},
{
desc: "should support deflate",
input: normalBytes,
expected: deflatedBytes,
encoding: "deflate",
encoding: compressutil.Deflate,
shouldMatch: false,
},
{
Expand Down Expand Up @@ -102,21 +102,21 @@ func TestDecode(t *testing.T) {
desc: "should support identity",
input: normalBytes,
expected: normalBytes,
encoding: "identity",
encoding: compressutil.Identity,
shouldMatch: true,
},
{
desc: "should support gzip",
input: gzippedBytes,
expected: normalBytes,
encoding: "gzip",
encoding: compressutil.Gzip,
shouldMatch: false,
},
{
desc: "should support deflate",
input: deflatedBytes,
expected: normalBytes,
encoding: "deflate",
encoding: compressutil.Deflate,
shouldMatch: false,
},
{
Expand Down
31 changes: 31 additions & 0 deletions config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package rewrite_body

import (
"regexp"

"github.com/packruler/rewrite-body/httputil"
)

// Rewrite holds one rewrite body configuration.
type Rewrite struct {
Regex string `json:"regex" yaml:"regex" toml:"regex"`
Replacement string `json:"replacement" yaml:"replacement" toml:"replacement"`
}

// Config holds the plugin configuration.
type Config struct {
LastModified bool `json:"lastModified" toml:"lastModified" yaml:"lastModified"`
Rewrites []Rewrite `json:"rewrites" toml:"rewrites" yaml:"rewrites"`
LogLevel int8 `json:"logLevel" toml:"logLevel" yaml:"logLevel"`
Monitoring httputil.MonitoringConfig `json:"monitoring" toml:"monitoring" yaml:"monitoring"`
}

// CreateConfig creates and initializes the plugin configuration.
func CreateConfig() *Config {
return &Config{}
}

type rewrite struct {
regex *regexp.Regexp
replacement []byte
}
9 changes: 9 additions & 0 deletions fixtures/sample.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[config]
lastModified = true
logLevel = 0
[[config.rewrites]]
regex = "test"
replacement = "test"
[config.monitor]
types = ["text/html"]
methods = ["GET"]
10 changes: 10 additions & 0 deletions fixtures/sample.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
config:
lastModified: true
logLevel: 0
monitor:
types:
- text/html
methods: ["GET"]
rewrites:
- regex: "test"
replacement: "test"
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
github.com/packruler/rewrite-body v0.1.4 h1:0JlKMJW7od3DCybLazMBejapOjIdgpwer/BtPqqXDmM=
github.com/packruler/rewrite-body v0.1.4/go.mod h1:QZdekGTvGSTiaWN5PR/dB91IccNbtClM2jpuwqOG4cg=
github.com/packruler/rewrite-body v0.1.5 h1:Z5/uT2I2rJ/9zJWSRMuXbIIt8ETDkv/aCl+OgVObpaI=
github.com/packruler/rewrite-body v0.1.5/go.mod h1:QZdekGTvGSTiaWN5PR/dB91IccNbtClM2jpuwqOG4cg=
21 changes: 21 additions & 0 deletions httputil/monitoring_config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package httputil

import "net/http"

// MonitoringConfig structure of data for handling configuration for
// controlling what content is monitored.
type MonitoringConfig struct {
Types []string `json:"types,omitempty" yaml:"types,omitempty" toml:"types,omitempty" export:"true"`
Methods []string `json:"methods,omitempty" yaml:"methods,omitempty" toml:"methods,omitempty" export:"true"`
}

// EnsureDefaults check Types and Methods for empty arrays and apply default values if found.
func (config *MonitoringConfig) EnsureDefaults() {
if len(config.Methods) == 0 {
config.Methods = []string{http.MethodGet}
}

if len(config.Types) == 0 {
config.Types = []string{"text/html"}
}
}
78 changes: 78 additions & 0 deletions httputil/monitoring_config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package httputil_test

import (
"net/http"
"testing"

"github.com/packruler/rewrite-body/httputil"
)

func TestMonitoringConfigParsing(t *testing.T) {
tests := []struct {
desc string
inputConfig httputil.MonitoringConfig
expectedConfig httputil.MonitoringConfig
}{
{
desc: "defaults will be supplied for empty arrays",
inputConfig: httputil.MonitoringConfig{
Types: []string{},
Methods: []string{},
},
expectedConfig: httputil.MonitoringConfig{
Types: []string{"text/html"},
Methods: []string{http.MethodGet},
},
},
{
desc: "defaults will be supplied for empty types with populated methods",
inputConfig: httputil.MonitoringConfig{
Types: []string{},
Methods: []string{"POST"},
},
expectedConfig: httputil.MonitoringConfig{
Types: []string{"text/html"},
Methods: []string{http.MethodPost},
},
},
{
desc: "defaults will be supplied for populated types with empty methods",
inputConfig: httputil.MonitoringConfig{
Types: []string{"application/json"},
Methods: []string{},
},
expectedConfig: httputil.MonitoringConfig{
Types: []string{"application/json"},
Methods: []string{http.MethodGet},
},
},
}

for _, test := range tests {
t.Run(test.desc, func(t *testing.T) {
config := test.inputConfig

config.EnsureDefaults()

if len(config.Types) != len(test.expectedConfig.Types) {
t.Errorf("Expected Types: '%v' | Got Types: '%v'", test.expectedConfig.Types, config.Types)
}

for i, v := range test.expectedConfig.Types {
if v != config.Types[i] {
t.Errorf("Expected Types: '%v' | Got Types: '%v'", test.expectedConfig.Types, config.Types)
}
}

if len(config.Methods) != len(test.expectedConfig.Methods) {
t.Errorf("Expected Methods: '%v' | Got Methods: '%v'", test.expectedConfig.Methods, config.Methods)
}

for i, v := range test.expectedConfig.Methods {
if v != config.Methods[i] {
t.Errorf("Expected Methods: '%v' | Got Methods: '%v'", test.expectedConfig.Methods, config.Methods)
}
}
})
}
}
Loading

0 comments on commit b57f614

Please sign in to comment.