controller2

package
v0.0.0-...-adbedf3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 13, 2023 License: BSD-3-Clause Imports: 14 Imported by: 0

Documentation

Overview

Example (NewProxy)
t := newTable(true)
p := newProxy("test-route", t, NewProxyConfig(false, "http://localhost:8080", []Header{{"name", "value"}, {"name2", "value2"}}, nil))
fmt.Printf("test: newProxy() -> [name:%v] [current:%v] [headers:%v]\n", p.name, p.config.Pattern, p.config.Headers)

p = newProxy("test-route2", t, NewProxyConfig(false, "https://google.com", nil, nil))
fmt.Printf("test: newProxy() -> [name:%v] [current:%v]\n", p.name, p.config.Pattern)

err := nilProxy.validate()
fmt.Printf("test: validate() -> [name:%v] [error:%v]\n", nilProxy.name, err)
err = p.validate()
fmt.Printf("test: validate() -> [name:%v] [error:%v]\n", p.name, err)

p2 := cloneProxy(p)
p2.config.Pattern = "urn:test"
fmt.Printf("test: cloneProxy() -> [prev-config:%v] [prev-name:%v] [curr-config:%v] [curr-name:%v]\n", p.config.Pattern, p.name, p2.config.Pattern, p2.name)
Output:

test: newProxy() -> [name:test-route] [current:http://localhost:8080] [headers:[{name value} {name2 value2}]]
test: newProxy() -> [name:test-route2] [current:https://google.com]
test: validate() -> [name:!] [error:<nil>]
test: validate() -> [name:test-route2] [error:<nil>]
test: cloneProxy() -> [prev-config:https://google.com] [prev-name:test-route2] [curr-config:urn:test] [curr-name:test-route2]
Example (NewRateLimiter)
t := newRateLimiter("test-route", newTable(true, false), NewRateLimiterConfig(true, 503, 1, 100))
fmt.Printf("test: newRateLimiter() -> [name:%v] [limit:%v] [burst:%v] [statusCode:%v]\n", t.name, t.config.Limit, t.config.Burst, t.StatusCode())

t = newRateLimiter("test-route2", newTable(true, false), NewRateLimiterConfig(true, 429, rate.Inf, DefaultBurst))
fmt.Printf("test: newRateLimiter() -> [name:%v] [limit:%v] [burst:%v] [statusCode:%v]\n", t.name, t.config.Limit, t.config.Burst, t.StatusCode())

t2 := cloneRateLimiter(t)
t2.config.Limit = 123
fmt.Printf("test: cloneRateLimiter() -> [prev-limit:%v] [prev-name:%v] [curr-limit:%v] [curr-name:%v]\n", t.config.Limit, t.name, t2.config.Limit, t2.name)
Output:

test: newRateLimiter() -> [name:test-route] [limit:1] [burst:100] [statusCode:503]
test: newRateLimiter() -> [name:test-route2] [limit:1.7976931348623157e+308] [burst:1] [statusCode:429]
test: cloneRateLimiter() -> [prev-limit:1.7976931348623157e+308] [prev-name:test-route2] [curr-limit:123] [curr-name:test-route2]
Example (NewTimeout)
tbl := newTable(true, false)

//errt := newTimeout("error-timeout", tbl, NewTimeoutConfig(true, 0, 0))
//err := errt.validate()
//fmt.Printf("test: validate() -> [name:%v] [error:%v]\n", errt.name, err)

err := nilTimeout.validate()
fmt.Printf("test: validate() -> [name:%v] [error:%v]\n", nilTimeout.name, err)

t := newTimeout("test-route", tbl, NewTimeoutConfig(true, 0, 100))
fmt.Printf("test: newTimeout() -> [name:%v] [current:%v]\n", t.name, t.config.Duration)

t = newTimeout("test-route2", tbl, NewTimeoutConfig(true, 503, time.Millisecond*2000))
fmt.Printf("test: newTimeout() -> [name:%v] [current:%v]\n", t.name, t.config.Duration)

t2 := cloneTimeout(t)
t2.config.Duration = time.Millisecond * 1000
fmt.Printf("test: cloneTimeout() -> [prev-config:%v] [prev-name:%v] [curr-config:%v] [curr-name:%v]\n", t.config, t.name, t2.config, t2.name)
Output:

test: validate() -> [name:!] [error:<nil>]
test: newTimeout() -> [name:test-route] [current:100ns]
test: newTimeout() -> [name:test-route2] [current:2s]
test: cloneTimeout() -> [prev-config:{true 503 2s}] [prev-name:test-route2] [curr-config:{true 503 1s}] [curr-name:test-route2]

Index

Examples

Constants

View Source
const (
	Start      = "start"
	DurationMs = "duration-ms"
	Traffic    = "traffic"
	RouteName  = "route"
	RequestId  = "request-id"
	Protocol   = "protocol"
	Method     = "method"
	Uri        = "uri"
	Host       = "host"
	Path       = "path"
	StatusCode = "status-code"
	TimeoutMs  = "timeout-ms"
	RateLimit  = "rate-limit"
	RateBurst  = "rate-burst"
	//RateThreshold  = "rate-threshold"
	ProxyName = "proxy"
	//ProxyThreshold = "proxy-threshold"
	StatusFlags = "status-flags"
)
View Source
const (
	BehaviorKey = "behavior"

	RateLimitKey = "limit"
	RateBurstKey = "burst"
	DurationKey  = "duration"
	EnabledKey   = "enabled"
	PatternKey   = "pattern"
	WaitKey      = "wait"
	PercentKey   = "pct"

	FalseValue = "false"
	TrueValue  = "true"

	TimeoutBehavior   = "timeout"
	RateLimitBehavior = "rate-limit"
	ProxyBehavior     = "proxy"

	NilPercentageValue = float64(-1)
)
View Source
const (
	StatusDeadlineExceeded = 4
	StatusRateLimited      = 94
)
View Source
const (
	RateLimitInfValue = 99999
	EgressTraffic     = "egress"
	IngressTraffic    = "ingress"
	PingTraffic       = "ping"

	HostControllerName    = "host"
	DefaultControllerName = "*"
	NilControllerName     = "!"
	NilBehaviorName       = "!"
	FromRouteHeaderName   = "from-route"
	RequestIdHeaderName   = "X-REQUEST-ID"
	RateLimitFlag         = "RL"
	UpstreamTimeoutFlag   = "UT"
)
View Source
const (
	InfValue     = "-1"
	DefaultBurst = 1
)

Variables

This section is empty.

Functions

func Apply

func Apply(ctx context.Context, statusCode func() int, uri, requestId, method string) (func(), context.Context, bool)

Apply - function to be used to apply a controller2

func CreateEgressLookup

func CreateEgressLookup(configs []Config)

func CreateIngressLookup

func CreateIngressLookup(configs []Config)

func ExtractState

func ExtractState(state, name string) string

func FormatLogJson

func FormatLogJson(traffic string, start time.Time, duration time.Duration, req *http.Request, resp *http.Response, routeName string, timeout int, rateLimit rate.Limit, rateBurst int, proxy, statusFlags string) string

func FormatLogText

func FormatLogText(traffic string, start time.Time, duration time.Duration, req *http.Request, resp *http.Response, routeName string, timeout int, rateLimit rate.Limit, rateBurst int, proxy, statusFlags string) string

func InitEgressControllers

func InitEgressControllers(read func() ([]byte, error)) []error

func InitIngressControllers

func InitIngressControllers(read func() ([]byte, error)) []error

func IsDisable

func IsDisable(values url.Values) bool

IsDisable returns true if the values contains a key named "enabled" and its value is "false".

func IsEmpty

func IsEmpty(s string) bool

func IsEnable

func IsEnable(values url.Values) bool

func NewStatusCode

func NewStatusCode(status **runtime.Status) func() int

func NewValues

func NewValues(key, value string) url.Values

func ParseDuration

func ParseDuration(s string) (time.Duration, error)
Example
s := ""
duration, err := ParseDuration(s)
fmt.Printf("test: ParseDuration(\"%v\") [err:%v] [duration:%v]\n", s, err, duration)

s = "  "
duration, err = ParseDuration(s)
fmt.Printf("test: ParseDuration(\"%v\") [err:%v] [duration:%v]\n", s, err, duration)

s = "12as"
duration, err = ParseDuration(s)
fmt.Printf("test: ParseDuration(\"%v\") [err:%v] [duration:%v]\n", s, err, duration)

s = "1000"
duration, err = ParseDuration(s)
fmt.Printf("test: ParseDuration(\"%v\") [err:%v] [duration:%v]\n", s, err, duration)

s = "1000s"
duration, err = ParseDuration(s)
fmt.Printf("test: ParseDuration(\"%v\") [err:%v] [duration:%v]\n", s, err, duration)

s = "1000m"
duration, err = ParseDuration(s)
fmt.Printf("test: ParseDuration(\"%v\") [err:%v] [duration:%v]\n", s, err, duration)

s = "1m"
duration, err = ParseDuration(s)
fmt.Printf("test: ParseDuration(\"%v\") [err:%v] [duration:%v]\n", s, err, duration)

s = "10ms"
duration, err = ParseDuration(s)
fmt.Printf("test: ParseDuration(\"%v\") [err:%v] [duration:%v]\n", s, err, duration)

//t := time.Microsecond * 100
//fmt.Printf("test: time.String %v\n", t.String())

s = "10µs"
duration, err = ParseDuration(s)
fmt.Printf("test: ParseDuration(\"%v\") [err:%v] [duration:%v]\n", s, err, duration)
Output:

test: ParseDuration("") [err:<nil>] [duration:0s]
test: ParseDuration("  ") [err:strconv.Atoi: parsing "  ": invalid syntax] [duration:0s]
test: ParseDuration("12as") [err:strconv.Atoi: parsing "12a": invalid syntax] [duration:0s]
test: ParseDuration("1000") [err:<nil>] [duration:16m40s]
test: ParseDuration("1000s") [err:<nil>] [duration:16m40s]
test: ParseDuration("1000m") [err:<nil>] [duration:16h40m0s]
test: ParseDuration("1m") [err:<nil>] [duration:1m0s]
test: ParseDuration("10ms") [err:<nil>] [duration:10ms]
test: ParseDuration("10µs") [err:<nil>] [duration:10µs]

func ParseLimitAndBurst

func ParseLimitAndBurst(values url.Values) (rate.Limit, int, error)

func ParsePercentage

func ParsePercentage(values url.Values) float64

func ParseState

func ParseState(s string) (names []string, values []string)

func SetExtractFn

func SetExtractFn(fn OutputHandler)

SetExtractFn - configuration for connector function

func SetLogFn

func SetLogFn(fn OutputHandler)

SetLogFn - configuration for logging function

func Trim

func Trim(s string) string

func UpdateEnable

func UpdateEnable(s State, values url.Values) (stateChange bool, err error)

func ValidateConfig

func ValidateConfig(config Config) []error

Types

type AccessLogHandler

type AccessLogHandler interface {
	Write(traffic string, start time.Time, duration time.Duration, req *http.Request, resp *http.Response, routeName string, timeout int, rateLimit rate.Limit, rateBurst int, rateThreshold, proxy, proxyThreshold, statusFlags string)
}

AccessLogHandler - template access log handler interface

type Actuator

type Actuator interface {
	Signal(values url.Values) error
}

type Config

type Config struct {
	Name        string
	Route       Route
	Timeout     *TimeoutConfig
	RateLimiter *RateLimiterConfig
	Proxy       *ProxyConfig
}

Config - configuration

func NewConfig

func NewConfig(name string, route Route, config ...any) Config

NewConfig - creates a new controller2 configuration

func NewConfigFromJson

func NewConfigFromJson(config ConfigJson) (Config, error)

NewConfigFromJson - creates a new route from a JSON configuration

func (Config) IsConfigured

func (r Config) IsConfigured() bool

type ConfigJson

type ConfigJson struct {
	Name        string
	Route       Route
	Timeout     *TimeoutConfigJson
	RateLimiter *RateLimiterConfig
	Proxy       *ProxyConfig
}

type Controller

type Controller interface {
	Actuator
	Name() string
	Timeout() Timeout
	RateLimiter() RateLimiter
	Proxy() Proxy
	UpdateHeaders(req *http.Request)
	LogHttpIngress(start time.Time, duration time.Duration, req *http.Request, statusCode int, written int64, statusFlags string)
	LogHttpEgress(start time.Time, duration time.Duration, req *http.Request, resp *http.Response, retry bool, statusFlags string)
	Log(start time.Time, duration time.Duration, statusCode int, uri, requestId, method, statusFlags string)
	// contains filtered or unexported methods
}

Controller - definition for properties of a controller2

Example (NewController)
t := newTable(true)
route := NewConfig("test", Route{}, "", false, NewTimeoutConfig(true, 0, time.Millisecond*1500), NewRateLimiterConfig(true, 503, 100, 10))

ctrl, _ := newController(route, t)
fmt.Printf("test: newController() -> [timeout:%v] [rateLimit:%v]\n", ctrl.Timeout().IsEnabled(), ctrl.RateLimiter().IsEnabled())

d := ctrl.timeout.Duration()
a1 := cloneController[*timeout](ctrl, newTimeout("new-timeout", t, NewTimeoutConfig(true, http.StatusGatewayTimeout, time.Millisecond*500)))

d1 := a1.timeout.Duration()
fmt.Printf("test: cloneController() -> [prev-duration:%v] [curr-duration:%v]\n", d, d1)
Output:

test: newController() -> [timeout:true] [rateLimit:true]
test: cloneController() -> [prev-duration:1.5s] [curr-duration:500ms]
Example (NewController_Error)
t := newTable(false)
route := NewConfig("test", Route{}, "", false, NewTimeoutConfig(true, 0, time.Millisecond*1500), NewRateLimiterConfig(true, 503, 100, 10))

_, errs := newController(route, t)
fmt.Printf("test: newController() -> [errs:%v]\n", errs)

route = NewConfig("test", Route{}, "", false, NewTimeoutConfig(true, 0, time.Millisecond*1500))
_, errs = newController(route, t)
fmt.Printf("test: newController() -> [errs:%v]\n", errs)

route = NewConfig("test", Route{}, "", false, NewTimeoutConfig(true, 0, -1))
_, errs = newController(route, t)
fmt.Printf("test: newController() -> [errs:%v]\n", errs)

route = NewConfig("test", Route{}, "", false, NewTimeoutConfig(true, 0, 10))
_, errs = newController(route, t)
fmt.Printf("test: newController() -> [errs:%v]\n", errs)

route = newConfig("test", NewRateLimiterConfig(true, 504, -1, 10))
_, errs = newController(route, t)
fmt.Printf("test: newController() -> [errs:%v]\n", errs)
Output:

test: newController() -> [errs:[]]
test: newController() -> [errs:[]]
test: newController() -> [errs:[invalid configuration: Timeout duration is < 0 [test]]]
test: newController() -> [errs:[]]
test: newController() -> [errs:[invalid configuration: RateLimiter limit is < 0 [test]]]
Example (NewController_config)
t := newTable(true)
route := NewConfig("test", Route{}, "", false, NewTimeoutConfig(true, 0, time.Millisecond*1500), nil, NewRateLimiterConfig(true, 503, 100, 10), nil)

ctrl, _ := newController(route, t)
fmt.Printf("test: newController() -> [timeout:%v] [rateLimit:%v]\n", ctrl.Timeout().IsEnabled(), ctrl.RateLimiter().IsEnabled())

//d := ctrl.timeout.Duration()
//ctrl1 := cloneController[*timeout](ctrl, newTimeout("new-timeout", t, NewTimeoutConfig(time.Millisecond*500, http.StatusGatewayTimeout)))

//d1 := ctrl1.timeout.Duration()
//fmt.Printf("test: cloneController() -> [prev-duration:%v] [curr-duration:%v]\n", d, d1)

//ctrl.Actuate(nil)
Output:

test: newController() -> [timeout:true] [rateLimit:true]

func EgressLookup

func EgressLookup(req *http.Request) (Controller, error)

func IngressLookup

func IngressLookup(req *http.Request) (Controller, error)

func IngressLookupHost

func IngressLookupHost() Controller

type DefaultHandler

type DefaultHandler struct{}

DefaultHandler - default handler

func (DefaultHandler) Apply

func (DefaultHandler) Apply(ctx context.Context, statusCode func() int, uri, requestId, method string) (func(), context.Context, bool)

Apply - function to be used to apply a controller2

type Handler

type Handler interface {
	Apply(ctx context.Context, statusCode func() int, uri, requestId, method string) (fn func(), newCtx context.Context, rateLimited bool)
}
type Header struct {
	Name  string
	Value string
}

type HeaderMatcher

type HeaderMatcher struct {
	Name        string
	StringMatch StringMatcher
}

type HttpMatcher

type HttpMatcher func(req *http.Request) (routeName string, ok bool)

HttpMatcher - type for Ingress/Egress table lookups by request

type LogAccessLog

type LogAccessLog struct{}

func (LogAccessLog) Write

func (LogAccessLog) Write(traffic string, start time.Time, duration time.Duration, req *http.Request, resp *http.Response, routeName string, timeout int, rateLimit rate.Limit, rateBurst int, proxy, statusFlags string)

type Match

type Match struct {
	Path            string
	Prefix          string
	Headers         []HeaderMatcher
	QueryParameters []QueryParameterMatcher
}

func (Match) IsMatch

func (m Match) IsMatch(req *http.Request) bool

type NilHandler

type NilHandler struct{}

NilHandler - nil handler

func (NilHandler) Apply

func (NilHandler) Apply(ctx context.Context, statusCode func() int, uri, requestId, method string) (func(), context.Context, bool)

Apply - function to be used to apply a controller2

type OutputHandler

type OutputHandler func(traffic string, start time.Time, duration time.Duration, req *http.Request, resp *http.Response, routeName string, timeout int, rateLimit rate.Limit, rateBurst int, proxy, statusFlags string)

OutputHandler - type for output handling

type Proxy

type Proxy interface {
	State
	Actuator
	Action() Actuator
	SetAction(action Actuator) error
	Pattern() string
	Headers() []Header
	BuildUrl(uri *url.URL) *url.URL
}

Proxy - interface for proxy

type ProxyConfig

type ProxyConfig struct {
	Enabled bool
	Pattern string
	Headers []Header
	Action  Actuator
}

func NewProxyConfig

func NewProxyConfig(enabled bool, pattern string, headers []Header, action Actuator) *ProxyConfig

type QueryParameterMatcher

type QueryParameterMatcher struct {
	Name         string
	StringMatch  StringMatcher
	PresentMatch bool
}

type RateLimiter

type RateLimiter interface {
	State
	Actuator
	Allow() bool
	StatusCode() int
	Limit() rate.Limit
	Burst() int
}

RateLimiter - interface for rate limiting

type RateLimiterConfig

type RateLimiterConfig struct {
	Enabled    bool
	StatusCode int
	Limit      rate.Limit
	Burst      int
}

func NewRateLimiterConfig

func NewRateLimiterConfig(enabled bool, statusCode int, limit rate.Limit, burst int) *RateLimiterConfig

type Route

type Route struct {
	Match Match
	Url   string
}

func (Route) Validate

func (r Route) Validate(name string) []error

type State

type State interface {
	IsEnabled() bool
	IsNil() bool
	Enable()
	Disable()
}

State - defines enabled state

type StdioAccessLog

type StdioAccessLog struct{}

func (StdioAccessLog) Write

func (StdioAccessLog) Write(traffic string, start time.Time, duration time.Duration, req *http.Request, resp *http.Response, routeName string, timeout int, rateLimit rate.Limit, rateBurst int, proxy, statusFlags string)

type StringMatcher

type StringMatcher struct {
	Exact  string
	Prefix string
	//"suffix": ...,
	//"safe_regex": {...},
	//"contains": ...,
	IgnoreCase bool
}

type Timeout

type Timeout interface {
	State
	Actuator
	StatusCode() int
	Duration() time.Duration
}

Timeout - interface for timeouts

type TimeoutConfig

type TimeoutConfig struct {
	Enabled    bool
	StatusCode int
	Duration   time.Duration
}

func NewTimeoutConfig

func NewTimeoutConfig(enabled bool, statusCode int, duration time.Duration) *TimeoutConfig

type TimeoutConfigJson

type TimeoutConfigJson struct {
	Enabled    bool
	StatusCode int
	Duration   string
}

type UriMatcher

type UriMatcher func(uri string, method string) (routeName string, ok bool)

UriMatcher - type for control table lookups by uri

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL