@marcel91200 / caddy Mirror · read-only / commits / 52822a41
Fork 0

Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS

Mirrored from https://github.com/Slazee/caddy.git

Synced Nov 12, 15:45 UTC

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 <lavofr@gmail.com> Co-authored-by: Matt Holt <mholt@users.noreply.github.com> Co-authored-by: Tristan Swadell @TristonianJones

jbrown-stripe committed Mar 13, 2024 at 23:32 UTC 52822a41cb94fcc9669cd7ba8ac1a0513e4d55f9
4 files changed +129 -135
go.mod
+3 -2
@@ -12,7 +12,7 @@ require (
12 github.com/caddyserver/certmagic v0.20.0
13 github.com/dustin/go-humanize v1.0.1
14 github.com/go-chi/chi/v5 v5.0.10
15 - github.com/google/cel-go v0.15.1
15 + github.com/google/cel-go v0.20.0
16 github.com/google/uuid v1.3.1
17 github.com/klauspost/compress v1.17.0
18 github.com/klauspost/cpuid/v2 v2.2.5
@@ -49,7 +49,7 @@ require (
49 require (
50 cloud.google.com/go/iam v1.1.2 // indirect
51 github.com/Microsoft/go-winio v0.6.0 // indirect
52 - github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df // indirect
52 + github.com/antlr4-go/antlr/v4 v4.13.0 // indirect
53 github.com/davecgh/go-spew v1.1.1 // indirect
54 github.com/fxamacker/cbor/v2 v2.5.0 // indirect
55 github.com/golang/glog v1.1.2 // indirect
@@ -70,6 +70,7 @@ require (
70 go.opentelemetry.io/contrib/propagators/jaeger v1.17.0 // indirect
71 go.opentelemetry.io/contrib/propagators/ot v1.17.0 // indirect
72 go.uber.org/mock v0.3.0 // indirect
73 + google.golang.org/genproto/googleapis/api v0.0.0-20231120223509-83a465c0220f // indirect
74 google.golang.org/genproto/googleapis/rpc v0.0.0-20231127180814-3a041ad873d4 // indirect
75 )
76
go.sum
+4 -4
@@ -44,8 +44,8 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuy
44 github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
45 github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
46 github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
47 -github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df h1:7RFfzj4SSt6nnvCPbCqijJi1nWCd+TqAT3bYCStRC18=
48 -github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df/go.mod h1:pSwJ0fSY5KhvocuWSx4fz3BA8OrA1bQn+K1Eli3BRwM=
47 +github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI=
48 +github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g=
49 github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
50 github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
51 github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
@@ -199,8 +199,8 @@ github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Z
199 github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
200 github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU=
201 github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
202 -github.com/google/cel-go v0.15.1 h1:iTgVZor2x9okXtmTrqO8cg4uvqIeaBcWhXtruaWFMYQ=
203 -github.com/google/cel-go v0.15.1/go.mod h1:YzWEoI07MC/a/wj9in8GeVatqfypkldgBlwXh9bCwqY=
202 +github.com/google/cel-go v0.20.0 h1:h4n6DOCppEMpWERzllyNkntl7JrDyxoE543KWS6BLpc=
203 +github.com/google/cel-go v0.20.0/go.mod h1:kWcIzTsPX0zmQ+H3TirHstLLf9ep5QTsZBN9u4dOYLg=
204 github.com/google/certificate-transparency-go v1.0.21/go.mod h1:QeJfpSbVSfYc7RgB3gJFj9cbuQMMchQxrWXz8Ruopmg=
205 github.com/google/certificate-transparency-go v1.1.8-0.20240110162603-74a5dd331745 h1:heyoXNxkRT155x4jTAiSv5BVSVkueifPUm+Q8LUXMRo=
206 github.com/google/certificate-transparency-go v1.1.8-0.20240110162603-74a5dd331745/go.mod h1:zN0wUQgV9LjwLZeFHnrAbQi8hzMVvEWePyk+MhPOk7k=
modules/caddyhttp/celmatcher.go
+65 -81
@@ -27,6 +27,7 @@ import (
27
28 "github.com/google/cel-go/cel"
29 "github.com/google/cel-go/common"
30 + "github.com/google/cel-go/common/ast"
31 "github.com/google/cel-go/common/operators"
32 "github.com/google/cel-go/common/types"
33 "github.com/google/cel-go/common/types/ref"
@@ -36,7 +37,6 @@ import (
37 "github.com/google/cel-go/interpreter/functions"
38 "github.com/google/cel-go/parser"
39 "go.uber.org/zap"
39 - exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1"
40
41 "github.com/caddyserver/caddy/v2"
42 "github.com/caddyserver/caddy/v2/caddyconfig/caddyfile"
@@ -66,7 +66,7 @@ type MatchExpression struct {
66
67 expandedExpr string
68 prg cel.Program
69 - ta ref.TypeAdapter
69 + ta types.Adapter
70
71 log *zap.Logger
72 }
@@ -227,7 +227,7 @@ func (m MatchExpression) caddyPlaceholderFunc(lhs, rhs ref.Val) ref.Val {
227 }
228
229 // httpRequestCELType is the type representation of a native HTTP request.
230 -var httpRequestCELType = types.NewTypeValue("http.Request", traits.ReceiverType)
230 +var httpRequestCELType = cel.ObjectType("http.Request", traits.ReceiverType)
231
232 // celHTTPRequest wraps an http.Request with ref.Val interface methods.
233 //
@@ -263,7 +263,7 @@ func (cr celHTTPRequest) Equal(other ref.Val) ref.Val {
263 func (celHTTPRequest) Type() ref.Type { return httpRequestCELType }
264 func (cr celHTTPRequest) Value() any { return cr }
265
266 -var pkixNameCELType = types.NewTypeValue("pkix.Name", traits.ReceiverType)
266 +var pkixNameCELType = cel.ObjectType("pkix.Name", traits.ReceiverType)
267
268 // celPkixName wraps an pkix.Name with
269 // methods to satisfy the ref.Val interface.
@@ -472,25 +472,20 @@ func CELMatcherRuntimeFunction(funcName string, fac CELMatcherFactory) functions
472 //
473 // The arguments are collected into a single list argument the following
474 // function call returned: <funcName>(request, [args])
475 -func celMatcherStringListMacroExpander(funcName string) parser.MacroExpander {
476 - return func(eh parser.ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) {
477 - matchArgs := []*exprpb.Expr{}
475 +func celMatcherStringListMacroExpander(funcName string) cel.MacroFactory {
476 + return func(eh cel.MacroExprFactory, target ast.Expr, args []ast.Expr) (ast.Expr, *common.Error) {
477 + matchArgs := []ast.Expr{}
478 if len(args) == 0 {
479 - return nil, &common.Error{
480 - Message: "matcher requires at least one argument",
481 - }
479 + return nil, eh.NewError(0, "matcher requires at least one argument")
480 }
481 for _, arg := range args {
482 if isCELStringExpr(arg) {
483 matchArgs = append(matchArgs, arg)
484 } else {
487 - return nil, &common.Error{
488 - Location: eh.OffsetLocation(arg.GetId()),
489 - Message: "matcher arguments must be string constants",
490 - }
485 + return nil, eh.NewError(arg.ID(), "matcher arguments must be string constants")
486 }
487 }
493 - return eh.GlobalCall(funcName, eh.Ident("request"), eh.NewList(matchArgs...)), nil
488 + return eh.NewCall(funcName, eh.NewIdent("request"), eh.NewList(matchArgs...)), nil
489 }
490 }
491
@@ -499,19 +494,14 @@ func celMatcherStringListMacroExpander(funcName string) parser.MacroExpander {
494 //
495 // The following function call is returned: <funcName>(request, arg)
496 func celMatcherStringMacroExpander(funcName string) parser.MacroExpander {
502 - return func(eh parser.ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) {
497 + return func(eh cel.MacroExprFactory, target ast.Expr, args []ast.Expr) (ast.Expr, *common.Error) {
498 if len(args) != 1 {
504 - return nil, &common.Error{
505 - Message: "matcher requires one argument",
506 - }
499 + return nil, eh.NewError(0, "matcher requires one argument")
500 }
501 if isCELStringExpr(args[0]) {
509 - return eh.GlobalCall(funcName, eh.Ident("request"), args[0]), nil
510 - }
511 - return nil, &common.Error{
512 - Location: eh.OffsetLocation(args[0].GetId()),
513 - Message: "matcher argument must be a string literal",
502 + return eh.NewCall(funcName, eh.NewIdent("request"), args[0]), nil
503 }
504 + return nil, eh.NewError(args[0].ID(), "matcher argument must be a string literal")
505 }
506 }
507
@@ -520,49 +510,35 @@ func celMatcherStringMacroExpander(funcName string) parser.MacroExpander {
510 //
511 // The following function call is returned: <funcName>(request, arg)
512 func celMatcherJSONMacroExpander(funcName string) parser.MacroExpander {
523 - return func(eh parser.ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) {
513 + return func(eh cel.MacroExprFactory, target ast.Expr, args []ast.Expr) (ast.Expr, *common.Error) {
514 if len(args) != 1 {
525 - return nil, &common.Error{
526 - Message: "matcher requires a map literal argument",
527 - }
515 + return nil, eh.NewError(0, "matcher requires a map literal argument")
516 }
517 arg := args[0]
530 - switch arg.GetExprKind().(type) {
531 - case *exprpb.Expr_StructExpr:
532 - structExpr := arg.GetStructExpr()
533 - if structExpr.GetMessageName() != "" {
534 - return nil, &common.Error{
535 - Location: eh.OffsetLocation(arg.GetId()),
536 - Message: fmt.Sprintf(
537 - "matcher input must be a map literal, not a %s",
538 - structExpr.GetMessageName(),
539 - ),
540 - }
541 - }
542 - for _, entry := range structExpr.GetEntries() {
543 - isStringPlaceholder := isCELStringExpr(entry.GetMapKey())
518 +
519 + switch arg.Kind() {
520 + case ast.StructKind:
521 + return nil, eh.NewError(arg.ID(),
522 + fmt.Sprintf("matcher input must be a map literal, not a %s", arg.AsStruct().TypeName()))
523 + case ast.MapKind:
524 + mapExpr := arg.AsMap()
525 + for _, entry := range mapExpr.Entries() {
526 + isStringPlaceholder := isCELStringExpr(entry.AsMapEntry().Key())
527 if !isStringPlaceholder {
545 - return nil, &common.Error{
546 - Location: eh.OffsetLocation(entry.GetId()),
547 - Message: "matcher map keys must be string literals",
548 - }
528 + return nil, eh.NewError(entry.ID(), "matcher map keys must be string literals")
529 }
550 - isStringListPlaceholder := isCELStringExpr(entry.GetValue()) ||
551 - isCELStringListLiteral(entry.GetValue())
530 + isStringListPlaceholder := isCELStringExpr(entry.AsMapEntry().Value()) ||
531 + isCELStringListLiteral(entry.AsMapEntry().Value())
532 if !isStringListPlaceholder {
553 - return nil, &common.Error{
554 - Location: eh.OffsetLocation(entry.GetValue().GetId()),
555 - Message: "matcher map values must be string or list literals",
556 - }
533 + return nil, eh.NewError(entry.AsMapEntry().Value().ID(), "matcher map values must be string or list literals")
534 }
535 }
559 - return eh.GlobalCall(funcName, eh.Ident("request"), arg), nil
536 + return eh.NewCall(funcName, eh.NewIdent("request"), arg), nil
537 + case ast.UnspecifiedExprKind, ast.CallKind, ast.ComprehensionKind, ast.IdentKind, ast.ListKind, ast.LiteralKind, ast.SelectKind:
538 + // appeasing the linter :)
539 }
540
562 - return nil, &common.Error{
563 - Location: eh.OffsetLocation(arg.GetId()),
564 - Message: "matcher requires a map literal argument",
565 - }
541 + return nil, eh.NewError(arg.ID(), "matcher requires a map literal argument")
542 }
543 }
544
@@ -607,69 +583,77 @@ func CELValueToMapStrList(data ref.Val) (map[string][]string, error) {
583 }
584
585 // isCELStringExpr indicates whether the expression is a supported string expression
610 -func isCELStringExpr(e *exprpb.Expr) bool {
586 +func isCELStringExpr(e ast.Expr) bool {
587 return isCELStringLiteral(e) || isCELCaddyPlaceholderCall(e) || isCELConcatCall(e)
588 }
589
590 // isCELStringLiteral returns whether the expression is a CEL string literal.
615 -func isCELStringLiteral(e *exprpb.Expr) bool {
616 - switch e.GetExprKind().(type) {
617 - case *exprpb.Expr_ConstExpr:
618 - constant := e.GetConstExpr()
619 - switch constant.GetConstantKind().(type) {
620 - case *exprpb.Constant_StringValue:
591 +func isCELStringLiteral(e ast.Expr) bool {
592 + switch e.Kind() {
593 + case ast.LiteralKind:
594 + constant := e.AsLiteral()
595 + switch constant.Type() {
596 + case types.StringType:
597 return true
598 }
599 + case ast.UnspecifiedExprKind, ast.CallKind, ast.ComprehensionKind, ast.IdentKind, ast.ListKind, ast.MapKind, ast.SelectKind, ast.StructKind:
600 + // appeasing the linter :)
601 }
602 return false
603 }
604
605 // isCELCaddyPlaceholderCall returns whether the expression is a caddy placeholder call.
628 -func isCELCaddyPlaceholderCall(e *exprpb.Expr) bool {
629 - switch e.GetExprKind().(type) {
630 - case *exprpb.Expr_CallExpr:
631 - call := e.GetCallExpr()
632 - if call.GetFunction() == "caddyPlaceholder" {
606 +func isCELCaddyPlaceholderCall(e ast.Expr) bool {
607 + switch e.Kind() {
608 + case ast.CallKind:
609 + call := e.AsCall()
610 + if call.FunctionName() == "caddyPlaceholder" {
611 return true
612 }
613 + case ast.UnspecifiedExprKind, ast.ComprehensionKind, ast.IdentKind, ast.ListKind, ast.LiteralKind, ast.MapKind, ast.SelectKind, ast.StructKind:
614 + // appeasing the linter :)
615 }
616 return false
617 }
618
619 // isCELConcatCall tests whether the expression is a concat function (+) with string, placeholder, or
620 // other concat call arguments.
641 -func isCELConcatCall(e *exprpb.Expr) bool {
642 - switch e.GetExprKind().(type) {
643 - case *exprpb.Expr_CallExpr:
644 - call := e.GetCallExpr()
645 - if call.GetTarget() != nil {
621 +func isCELConcatCall(e ast.Expr) bool {
622 + switch e.Kind() {
623 + case ast.CallKind:
624 + call := e.AsCall()
625 + if call.Target().Kind() != ast.UnspecifiedExprKind {
626 return false
627 }
648 - if call.GetFunction() != operators.Add {
628 + if call.FunctionName() != operators.Add {
629 return false
630 }
651 - for _, arg := range call.GetArgs() {
631 + for _, arg := range call.Args() {
632 if !isCELStringExpr(arg) {
633 return false
634 }
635 }
636 return true
637 + case ast.UnspecifiedExprKind, ast.ComprehensionKind, ast.IdentKind, ast.ListKind, ast.LiteralKind, ast.MapKind, ast.SelectKind, ast.StructKind:
638 + // appeasing the linter :)
639 }
640 return false
641 }
642
643 // isCELStringListLiteral returns whether the expression resolves to a list literal
644 // containing only string constants or a placeholder call.
663 -func isCELStringListLiteral(e *exprpb.Expr) bool {
664 - switch e.GetExprKind().(type) {
665 - case *exprpb.Expr_ListExpr:
666 - list := e.GetListExpr()
667 - for _, elem := range list.GetElements() {
645 +func isCELStringListLiteral(e ast.Expr) bool {
646 + switch e.Kind() {
647 + case ast.ListKind:
648 + list := e.AsList()
649 + for _, elem := range list.Elements() {
650 if !isCELStringExpr(elem) {
651 return false
652 }
653 }
654 return true
655 + case ast.UnspecifiedExprKind, ast.CallKind, ast.ComprehensionKind, ast.IdentKind, ast.LiteralKind, ast.MapKind, ast.SelectKind, ast.StructKind:
656 + // appeasing the linter :)
657 }
658 return false
659 }
modules/caddyhttp/fileserver/matcher.go
+57 -48
@@ -27,11 +27,12 @@ import (
27
28 "github.com/google/cel-go/cel"
29 "github.com/google/cel-go/common"
30 + "github.com/google/cel-go/common/ast"
31 "github.com/google/cel-go/common/operators"
32 + "github.com/google/cel-go/common/types"
33 "github.com/google/cel-go/common/types/ref"
34 "github.com/google/cel-go/parser"
35 "go.uber.org/zap"
34 - exprpb "google.golang.org/genproto/googleapis/api/expr/v1alpha1"
36
37 "github.com/caddyserver/caddy/v2"
38 "github.com/caddyserver/caddy/v2/caddyconfig/caddyfile"
@@ -220,30 +221,30 @@ func (MatchFile) CELLibrary(ctx caddy.Context) (cel.Library, error) {
221 }
222
223 func celFileMatcherMacroExpander() parser.MacroExpander {
223 - return func(eh parser.ExprHelper, target *exprpb.Expr, args []*exprpb.Expr) (*exprpb.Expr, *common.Error) {
224 + return func(eh parser.ExprHelper, target ast.Expr, args []ast.Expr) (ast.Expr, *common.Error) {
225 if len(args) == 0 {
225 - return eh.GlobalCall("file",
226 - eh.Ident("request"),
226 + return eh.NewCall("file",
227 + eh.NewIdent("request"),
228 eh.NewMap(),
229 ), nil
230 }
231 if len(args) == 1 {
232 arg := args[0]
233 if isCELStringLiteral(arg) || isCELCaddyPlaceholderCall(arg) {
233 - return eh.GlobalCall("file",
234 - eh.Ident("request"),
234 + return eh.NewCall("file",
235 + eh.NewIdent("request"),
236 eh.NewMap(eh.NewMapEntry(
236 - eh.LiteralString("try_files"),
237 + eh.NewLiteral(types.String("try_files")),
238 eh.NewList(arg),
239 false,
240 )),
241 ), nil
242 }
243 if isCELTryFilesLiteral(arg) {
243 - return eh.GlobalCall("file", eh.Ident("request"), arg), nil
244 + return eh.NewCall("file", eh.NewIdent("request"), arg), nil
245 }
246 return nil, &common.Error{
246 - Location: eh.OffsetLocation(arg.GetId()),
247 + Location: eh.OffsetLocation(arg.ID()),
248 Message: "matcher requires either a map or string literal argument",
249 }
250 }
@@ -251,15 +252,15 @@ func celFileMatcherMacroExpander() parser.MacroExpander {
252 for _, arg := range args {
253 if !(isCELStringLiteral(arg) || isCELCaddyPlaceholderCall(arg)) {
254 return nil, &common.Error{
254 - Location: eh.OffsetLocation(arg.GetId()),
255 + Location: eh.OffsetLocation(arg.ID()),
256 Message: "matcher only supports repeated string literal arguments",
257 }
258 }
259 }
259 - return eh.GlobalCall("file",
260 - eh.Ident("request"),
260 + return eh.NewCall("file",
261 + eh.NewIdent("request"),
262 eh.NewMap(eh.NewMapEntry(
262 - eh.LiteralString("try_files"),
263 + eh.NewLiteral(types.String("try_files")),
264 eh.NewList(args...),
265 false,
266 )),
@@ -569,20 +570,17 @@ func indexFold(haystack, needle string) int {
570
571 // isCELTryFilesLiteral returns whether the expression resolves to a map literal containing
572 // only string keys with or a placeholder call.
572 -func isCELTryFilesLiteral(e *exprpb.Expr) bool {
573 - switch e.GetExprKind().(type) {
574 - case *exprpb.Expr_StructExpr:
575 - structExpr := e.GetStructExpr()
576 - if structExpr.GetMessageName() != "" {
577 - return false
578 - }
579 - for _, entry := range structExpr.GetEntries() {
580 - mapKey := entry.GetMapKey()
581 - mapVal := entry.GetValue()
573 +func isCELTryFilesLiteral(e ast.Expr) bool {
574 + switch e.Kind() {
575 + case ast.MapKind:
576 + mapExpr := e.AsMap()
577 + for _, entry := range mapExpr.Entries() {
578 + mapKey := entry.AsMapEntry().Key()
579 + mapVal := entry.AsMapEntry().Value()
580 if !isCELStringLiteral(mapKey) {
581 return false
582 }
585 - mapKeyStr := mapKey.GetConstExpr().GetStringValue()
583 + mapKeyStr := mapKey.AsLiteral().ConvertToType(types.StringType).Value()
584 if mapKeyStr == "try_files" || mapKeyStr == "split_path" {
585 if !isCELStringListLiteral(mapVal) {
586 return false
@@ -596,74 +594,85 @@ func isCELTryFilesLiteral(e *exprpb.Expr) bool {
594 }
595 }
596 return true
597 +
598 + case ast.UnspecifiedExprKind, ast.CallKind, ast.ComprehensionKind, ast.IdentKind, ast.ListKind, ast.LiteralKind, ast.SelectKind, ast.StructKind:
599 + // appeasing the linter :)
600 }
601 return false
602 }
603
604 // isCELStringExpr indicates whether the expression is a supported string expression
604 -func isCELStringExpr(e *exprpb.Expr) bool {
605 +func isCELStringExpr(e ast.Expr) bool {
606 return isCELStringLiteral(e) || isCELCaddyPlaceholderCall(e) || isCELConcatCall(e)
607 }
608
609 // isCELStringLiteral returns whether the expression is a CEL string literal.
609 -func isCELStringLiteral(e *exprpb.Expr) bool {
610 - switch e.GetExprKind().(type) {
611 - case *exprpb.Expr_ConstExpr:
612 - constant := e.GetConstExpr()
613 - switch constant.GetConstantKind().(type) {
614 - case *exprpb.Constant_StringValue:
610 +func isCELStringLiteral(e ast.Expr) bool {
611 + switch e.Kind() {
612 + case ast.LiteralKind:
613 + constant := e.AsLiteral()
614 + switch constant.Type() {
615 + case types.StringType:
616 return true
617 }
618 + case ast.UnspecifiedExprKind, ast.CallKind, ast.ComprehensionKind, ast.IdentKind, ast.ListKind, ast.MapKind, ast.SelectKind, ast.StructKind:
619 + // appeasing the linter :)
620 }
621 return false
622 }
623
624 // isCELCaddyPlaceholderCall returns whether the expression is a caddy placeholder call.
622 -func isCELCaddyPlaceholderCall(e *exprpb.Expr) bool {
623 - switch e.GetExprKind().(type) {
624 - case *exprpb.Expr_CallExpr:
625 - call := e.GetCallExpr()
626 - if call.GetFunction() == "caddyPlaceholder" {
625 +func isCELCaddyPlaceholderCall(e ast.Expr) bool {
626 + switch e.Kind() {
627 + case ast.CallKind:
628 + call := e.AsCall()
629 + if call.FunctionName() == "caddyPlaceholder" {
630 return true
631 }
632 + case ast.UnspecifiedExprKind, ast.ComprehensionKind, ast.IdentKind, ast.ListKind, ast.LiteralKind, ast.MapKind, ast.SelectKind, ast.StructKind:
633 + // appeasing the linter :)
634 }
635 return false
636 }
637
638 // isCELConcatCall tests whether the expression is a concat function (+) with string, placeholder, or
639 // other concat call arguments.
635 -func isCELConcatCall(e *exprpb.Expr) bool {
636 - switch e.GetExprKind().(type) {
637 - case *exprpb.Expr_CallExpr:
638 - call := e.GetCallExpr()
639 - if call.GetTarget() != nil {
640 +func isCELConcatCall(e ast.Expr) bool {
641 + switch e.Kind() {
642 + case ast.CallKind:
643 + call := e.AsCall()
644 + if call.Target().Kind() != ast.UnspecifiedExprKind {
645 return false
646 }
642 - if call.GetFunction() != operators.Add {
647 + if call.FunctionName() != operators.Add {
648 return false
649 }
645 - for _, arg := range call.GetArgs() {
650 + for _, arg := range call.Args() {
651 if !isCELStringExpr(arg) {
652 return false
653 }
654 }
655 return true
656 + case ast.UnspecifiedExprKind, ast.ComprehensionKind, ast.IdentKind, ast.ListKind, ast.LiteralKind, ast.MapKind, ast.SelectKind, ast.StructKind:
657 + // appeasing the linter :)
658 }
659 return false
660 }
661
662 // isCELStringListLiteral returns whether the expression resolves to a list literal
663 // containing only string constants or a placeholder call.
657 -func isCELStringListLiteral(e *exprpb.Expr) bool {
658 - switch e.GetExprKind().(type) {
659 - case *exprpb.Expr_ListExpr:
660 - list := e.GetListExpr()
661 - for _, elem := range list.GetElements() {
664 +func isCELStringListLiteral(e ast.Expr) bool {
665 + switch e.Kind() {
666 + case ast.ListKind:
667 + list := e.AsList()
668 + for _, elem := range list.Elements() {
669 if !isCELStringExpr(elem) {
670 return false
671 }
672 }
673 return true
674 + case ast.UnspecifiedExprKind, ast.CallKind, ast.ComprehensionKind, ast.IdentKind, ast.LiteralKind, ast.MapKind, ast.SelectKind, ast.StructKind:
675 + // appeasing the linter :)
676 }
677 return false
678 }