aboutsummaryrefslogtreecommitdiffhomepage
path: root/modules/caddyhttp/celmatcher.go
diff options
context:
space:
mode:
authorjbrown-stripe <[email protected]>2024-03-13 23:32:42 -0400
committerGitHub <[email protected]>2024-03-13 21:32:42 -0600
commit52822a41cb94fcc9669cd7ba8ac1a0513e4d55f9 (patch)
tree1674b468321813b6319be0d2a0b7ab8e3bbcfe1c /modules/caddyhttp/celmatcher.go
parent5b5f8feaf73b3cd0044fa08803ce65cd5cf2e2fb (diff)
downloadcaddy-52822a41cb94fcc9669cd7ba8ac1a0513e4d55f9.tar.gz
caddy-52822a41cb94fcc9669cd7ba8ac1a0513e4d55f9.zip
caddyhttp: upgrade to cel v0.20.0 (#6161)
* upgrade to cel v0.20.0 * Attempt to address feedback and fix linter * Let's try this * Take that, you linter! * Oh there's more --------- Co-authored-by: Francis Lavoie <[email protected]> Co-authored-by: Matt Holt <[email protected]> Co-authored-by: Tristan Swadell @TristonianJones
Diffstat (limited to 'modules/caddyhttp/celmatcher.go')
-rw-r--r--modules/caddyhttp/celmatcher.go146
1 files changed, 65 insertions, 81 deletions
diff --git a/modules/caddyhttp/celmatcher.go b/modules/caddyhttp/celmatcher.go
index 376135364..e1f15e869 100644
--- a/modules/caddyhttp/celmatcher.go
+++ b/modules/caddyhttp/celmatcher.go
@@ -27,6 +27,7 @@ import (
"github.com/google/cel-go/cel"
"github.com/google/cel-go/common"
+ "github.com/google/cel-go/common/ast"
"github.com/google/cel-go/common/operators"
"github.com/google/cel-go/common/types"
"github.com/google/cel-go/common/types/ref"
@@ -36,7 +37,6 @@ import (
"github.com/google/cel-go/interpreter/functions"
"github.com/google/cel-go/parser"
"go.uber.org/zap"
- exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1"
"github.com/caddyserver/caddy/v2"
"github.com/caddyserver/caddy/v2/caddyconfig/caddyfile"
@@ -66,7 +66,7 @@ type MatchExpression struct {
expandedExpr string
prg cel.Program
- ta ref.TypeAdapter
+ ta types.Adapter
log *zap.Logger
}
@@ -227,7 +227,7 @@ func (m MatchExpression) caddyPlaceholderFunc(lhs, rhs ref.Val) ref.Val {
}
// httpRequestCELType is the type representation of a native HTTP request.
-var httpRequestCELType = types.NewTypeValue("http.Request", traits.ReceiverType)
+var httpRequestCELType = cel.ObjectType("http.Request", traits.ReceiverType)
// celHTTPRequest wraps an http.Request with ref.Val interface methods.
//
@@ -263,7 +263,7 @@ func (cr celHTTPRequest) Equal(other ref.Val) ref.Val {
func (celHTTPRequest) Type() ref.Type { return httpRequestCELType }
func (cr celHTTPRequest) Value() any { return cr }
-var pkixNameCELType = types.NewTypeValue("pkix.Name", traits.ReceiverType)
+var pkixNameCELType = cel.ObjectType("pkix.Name", traits.ReceiverType)
// celPkixName wraps an pkix.Name with
// methods to satisfy the ref.Val interface.
@@ -472,25 +472,20 @@ func CELMatcherRuntimeFunction(funcName string, fac CELMatcherFactory) functions
//
// The arguments are collected into a single list argument the following
// function call returned: <funcName>(request, [args])
-func celMatcherStringListMacroExpander(funcName string) parser.MacroExpander {
- return func(eh parser.ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) {
- matchArgs := []*exprpb.Expr{}
+func celMatcherStringListMacroExpander(funcName string) cel.MacroFactory {
+ return func(eh cel.MacroExprFactory, target ast.Expr, args []ast.Expr) (ast.Expr, *common.Error) {
+ matchArgs := []ast.Expr{}
if len(args) == 0 {
- return nil, &common.Error{
- Message: "matcher requires at least one argument",
- }
+ return nil, eh.NewError(0, "matcher requires at least one argument")
}
for _, arg := range args {
if isCELStringExpr(arg) {
matchArgs = append(matchArgs, arg)
} else {
- return nil, &common.Error{
- Location: eh.OffsetLocation(arg.GetId()),
- Message: "matcher arguments must be string constants",
- }
+ return nil, eh.NewError(arg.ID(), "matcher arguments must be string constants")
}
}
- return eh.GlobalCall(funcName, eh.Ident("request"), eh.NewList(matchArgs...)), nil
+ return eh.NewCall(funcName, eh.NewIdent("request"), eh.NewList(matchArgs...)), nil
}
}
@@ -499,19 +494,14 @@ func celMatcherStringListMacroExpander(funcName string) parser.MacroExpander {
//
// The following function call is returned: <funcName>(request, arg)
func celMatcherStringMacroExpander(funcName string) parser.MacroExpander {
- return func(eh parser.ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) {
+ return func(eh cel.MacroExprFactory, target ast.Expr, args []ast.Expr) (ast.Expr, *common.Error) {
if len(args) != 1 {
- return nil, &common.Error{
- Message: "matcher requires one argument",
- }
+ return nil, eh.NewError(0, "matcher requires one argument")
}
if isCELStringExpr(args[0]) {
- return eh.GlobalCall(funcName, eh.Ident("request"), args[0]), nil
- }
- return nil, &common.Error{
- Location: eh.OffsetLocation(args[0].GetId()),
- Message: "matcher argument must be a string literal",
+ return eh.NewCall(funcName, eh.NewIdent("request"), args[0]), nil
}
+ return nil, eh.NewError(args[0].ID(), "matcher argument must be a string literal")
}
}
@@ -520,49 +510,35 @@ func celMatcherStringMacroExpander(funcName string) parser.MacroExpander {
//
// The following function call is returned: <funcName>(request, arg)
func celMatcherJSONMacroExpander(funcName string) parser.MacroExpander {
- return func(eh parser.ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) {
+ return func(eh cel.MacroExprFactory, target ast.Expr, args []ast.Expr) (ast.Expr, *common.Error) {
if len(args) != 1 {
- return nil, &common.Error{
- Message: "matcher requires a map literal argument",
- }
+ return nil, eh.NewError(0, "matcher requires a map literal argument")
}
arg := args[0]
- switch arg.GetExprKind().(type) {
- case *exprpb.Expr_StructExpr:
- structExpr := arg.GetStructExpr()
- if structExpr.GetMessageName() != "" {
- return nil, &common.Error{
- Location: eh.OffsetLocation(arg.GetId()),
- Message: fmt.Sprintf(
- "matcher input must be a map literal, not a %s",
- structExpr.GetMessageName(),
- ),
- }
- }
- for _, entry := range structExpr.GetEntries() {
- isStringPlaceholder := isCELStringExpr(entry.GetMapKey())
+
+ switch arg.Kind() {
+ case ast.StructKind:
+ return nil, eh.NewError(arg.ID(),
+ fmt.Sprintf("matcher input must be a map literal, not a %s", arg.AsStruct().TypeName()))
+ case ast.MapKind:
+ mapExpr := arg.AsMap()
+ for _, entry := range mapExpr.Entries() {
+ isStringPlaceholder := isCELStringExpr(entry.AsMapEntry().Key())
if !isStringPlaceholder {
- return nil, &common.Error{
- Location: eh.OffsetLocation(entry.GetId()),
- Message: "matcher map keys must be string literals",
- }
+ return nil, eh.NewError(entry.ID(), "matcher map keys must be string literals")
}
- isStringListPlaceholder := isCELStringExpr(entry.GetValue()) ||
- isCELStringListLiteral(entry.GetValue())
+ isStringListPlaceholder := isCELStringExpr(entry.AsMapEntry().Value()) ||
+ isCELStringListLiteral(entry.AsMapEntry().Value())
if !isStringListPlaceholder {
- return nil, &common.Error{
- Location: eh.OffsetLocation(entry.GetValue().GetId()),
- Message: "matcher map values must be string or list literals",
- }
+ return nil, eh.NewError(entry.AsMapEntry().Value().ID(), "matcher map values must be string or list literals")
}
}
- return eh.GlobalCall(funcName, eh.Ident("request"), arg), nil
+ return eh.NewCall(funcName, eh.NewIdent("request"), arg), nil
+ case ast.UnspecifiedExprKind, ast.CallKind, ast.ComprehensionKind, ast.IdentKind, ast.ListKind, ast.LiteralKind, ast.SelectKind:
+ // appeasing the linter :)
}
- return nil, &common.Error{
- Location: eh.OffsetLocation(arg.GetId()),
- Message: "matcher requires a map literal argument",
- }
+ return nil, eh.NewError(arg.ID(), "matcher requires a map literal argument")
}
}
@@ -607,69 +583,77 @@ func CELValueToMapStrList(data ref.Val) (map[string][]string, error) {
}
// isCELStringExpr indicates whether the expression is a supported string expression
-func isCELStringExpr(e *exprpb.Expr) bool {
+func isCELStringExpr(e ast.Expr) bool {
return isCELStringLiteral(e) || isCELCaddyPlaceholderCall(e) || isCELConcatCall(e)
}
// isCELStringLiteral returns whether the expression is a CEL string literal.
-func isCELStringLiteral(e *exprpb.Expr) bool {
- switch e.GetExprKind().(type) {
- case *exprpb.Expr_ConstExpr:
- constant := e.GetConstExpr()
- switch constant.GetConstantKind().(type) {
- case *exprpb.Constant_StringValue:
+func isCELStringLiteral(e ast.Expr) bool {
+ switch e.Kind() {
+ case ast.LiteralKind:
+ constant := e.AsLiteral()
+ switch constant.Type() {
+ case types.StringType:
return true
}
+ case ast.UnspecifiedExprKind, ast.CallKind, ast.ComprehensionKind, ast.IdentKind, ast.ListKind, ast.MapKind, ast.SelectKind, ast.StructKind:
+ // appeasing the linter :)
}
return false
}
// isCELCaddyPlaceholderCall returns whether the expression is a caddy placeholder call.
-func isCELCaddyPlaceholderCall(e *exprpb.Expr) bool {
- switch e.GetExprKind().(type) {
- case *exprpb.Expr_CallExpr:
- call := e.GetCallExpr()
- if call.GetFunction() == "caddyPlaceholder" {
+func isCELCaddyPlaceholderCall(e ast.Expr) bool {
+ switch e.Kind() {
+ case ast.CallKind:
+ call := e.AsCall()
+ if call.FunctionName() == "caddyPlaceholder" {
return true
}
+ case ast.UnspecifiedExprKind, ast.ComprehensionKind, ast.IdentKind, ast.ListKind, ast.LiteralKind, ast.MapKind, ast.SelectKind, ast.StructKind:
+ // appeasing the linter :)
}
return false
}
// isCELConcatCall tests whether the expression is a concat function (+) with string, placeholder, or
// other concat call arguments.
-func isCELConcatCall(e *exprpb.Expr) bool {
- switch e.GetExprKind().(type) {
- case *exprpb.Expr_CallExpr:
- call := e.GetCallExpr()
- if call.GetTarget() != nil {
+func isCELConcatCall(e ast.Expr) bool {
+ switch e.Kind() {
+ case ast.CallKind:
+ call := e.AsCall()
+ if call.Target().Kind() != ast.UnspecifiedExprKind {
return false
}
- if call.GetFunction() != operators.Add {
+ if call.FunctionName() != operators.Add {
return false
}
- for _, arg := range call.GetArgs() {
+ for _, arg := range call.Args() {
if !isCELStringExpr(arg) {
return false
}
}
return true
+ case ast.UnspecifiedExprKind, ast.ComprehensionKind, ast.IdentKind, ast.ListKind, ast.LiteralKind, ast.MapKind, ast.SelectKind, ast.StructKind:
+ // appeasing the linter :)
}
return false
}
// isCELStringListLiteral returns whether the expression resolves to a list literal
// containing only string constants or a placeholder call.
-func isCELStringListLiteral(e *exprpb.Expr) bool {
- switch e.GetExprKind().(type) {
- case *exprpb.Expr_ListExpr:
- list := e.GetListExpr()
- for _, elem := range list.GetElements() {
+func isCELStringListLiteral(e ast.Expr) bool {
+ switch e.Kind() {
+ case ast.ListKind:
+ list := e.AsList()
+ for _, elem := range list.Elements() {
if !isCELStringExpr(elem) {
return false
}
}
return true
+ case ast.UnspecifiedExprKind, ast.CallKind, ast.ComprehensionKind, ast.IdentKind, ast.LiteralKind, ast.MapKind, ast.SelectKind, ast.StructKind:
+ // appeasing the linter :)
}
return false
}