in confgenerator/filter/internal/ast/ast.go [441:487]
func (r Restriction) FluentConfig(tag, key string) ([]fluentbit.Component, string) {
lhs, _ := r.LHS.LuaAccessor(false)
rhsQuoted := LuaQuote(r.RHS)
rhsRegex := escapeWhitespaceFluentBit(r.RHS)
// TODO: Add support for numeric comparisons
var expr string
switch r.Operator {
case "GLOBAL", "<", "<=", ">", ">=":
panic(fmt.Errorf("unimplemented operator: %s", r.Operator))
case ":":
// substring match, case insensitive
expr = fmt.Sprintf(`(string.find(string.lower(tostring(v)), string.lower(%s), 1, false) ~= nil)`, rhsQuoted)
case "=~", "!~":
// regex match, case sensitive
// TODO: Re-implement using Lua once regex is supported. Lua has been shown to perform better
// than the next/modify/lift pattern used here, but we are unable to use Lua for now since
// it does not yet support regex.
c := modify(tag, key)
lhsRA, err := r.LHS.RecordAccessor()
if err != nil {
panic(fmt.Errorf("LHS %v couldn't parse: %w", r.LHS, err))
}
if r.Operator == "=~" {
c.Config["Condition"] = cond("Key_value_matches", lhsRA, rhsRegex)
} else {
c.OrderedConfig = append(c.OrderedConfig, [2]string{"Condition", cond("Key_value_does_not_match", lhsRA, rhsRegex)})
}
return []fluentbit.Component{c}, fmt.Sprintf(`(record[%s] ~= nil)`, LuaQuote(key))
case "=":
// equality, case insensitive
expr = fmt.Sprintf(`(string.lower(tostring(v)) == string.lower(%s))`, rhsQuoted)
case "!=":
// inequality, case insensitive
expr = fmt.Sprintf(`(string.lower(tostring(v)) ~= string.lower(%s))`, rhsQuoted)
}
if expr != "" {
// All comparisons involving a missing field are false
return nil, fmt.Sprintf(`(function(v) if v == nil then return false end return %s end)(%s)`, expr, lhs)
}
// This is all the supported operators.
panic(fmt.Errorf("unknown operator: %s", r.Operator))
}