1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2024-12-15 17:51:20 +00:00
kyverno/pkg/engine/context/mock_context.go
Charles-Edouard Brétéché 0099ef54ad
chore: enable gofmt and gofumpt linters (#3931)
Signed-off-by: Charles-Edouard Brétéché <charled.breteche@gmail.com>
2022-05-17 06:19:03 +00:00

101 lines
2.5 KiB
Go

package context
import (
"fmt"
"regexp"
"strings"
"sync"
wildcard "github.com/kyverno/go-wildcard"
"github.com/kyverno/kyverno/pkg/engine/jmespath"
)
// MockContext is used for testing and validation of variables
type MockContext struct {
mutex sync.RWMutex
re *regexp.Regexp
allowedPatterns []string
}
// NewMockContext creates a new MockContext that allows variables matching the supplied list of wildcard patterns
func NewMockContext(re *regexp.Regexp, vars ...string) *MockContext {
return &MockContext{re: re, allowedPatterns: vars}
}
// AddVariable adds given wildcardPattern to the allowed variable patterns
func (ctx *MockContext) AddVariable(wildcardPattern string) {
ctx.mutex.Lock()
defer ctx.mutex.Unlock()
builtInVarsCopy := ctx.allowedPatterns
ctx.allowedPatterns = append(builtInVarsCopy, wildcardPattern)
}
// Query the JSON context with JMESPATH search path
func (ctx *MockContext) Query(query string) (interface{}, error) {
query = strings.TrimSpace(query)
if query == "" {
return nil, fmt.Errorf("invalid query (nil)")
}
var emptyResult interface{}
// compile the query
_, err := jmespath.New(query)
if err != nil {
return emptyResult, fmt.Errorf("invalid JMESPath query %s: %v", query, err)
}
// strip escaped quotes from JMESPath variables with dashes e.g. {{ \"my-map.data\".key }}
query = strings.Replace(query, "\"", "", -1)
if ctx.re != nil && ctx.re.MatchString(query) {
return emptyResult, nil
}
if ctx.isVariableDefined(query) {
return emptyResult, nil
}
return emptyResult, InvalidVariableError{
variable: query,
re: ctx.re,
allowedPatterns: ctx.allowedPatterns,
}
}
func (ctx *MockContext) isVariableDefined(variable string) bool {
for _, pattern := range ctx.getVariables() {
if wildcard.Match(pattern, variable) {
return true
}
}
return false
}
func (ctx *MockContext) getVariables() []string {
ctx.mutex.RLock()
defer ctx.mutex.RUnlock()
vars := ctx.allowedPatterns
return vars
}
// InvalidVariableError represents error for non-white-listed variables
type InvalidVariableError struct {
variable string
re *regexp.Regexp
allowedPatterns []string
}
func (i InvalidVariableError) Error() string {
if i.re == nil {
return fmt.Sprintf("variable %s must match patterns %v", i.variable, i.allowedPatterns)
}
return fmt.Sprintf("variable %s must match regex \"%s\" or patterns %v", i.variable, i.re.String(), i.allowedPatterns)
}
func (ctx *MockContext) HasChanged(_ string) (bool, error) {
return false, nil
}