fleet/orbit/pkg/table/tablehelpers/getconstraints.go
Jahziel Villasana-Espinoza 87f4a28419
fix: use zerolog for orbit osquery table logging (#20028)
> Related issue: #19886 

# Checklist for submitter

If some of the following don't apply, delete the relevant line.

<!-- Note that API documentation changes are now addressed by the
product design team. -->

- [x] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.
See [Changes
files](https://fleetdm.com/docs/contributing/committing-changes#changes-files)
for more information.
- [x] Added/updated tests
- [x] Manual QA for all new/changed functionality
  - For Orbit and Fleet Desktop changes:
- [x] Manual QA must be performed in the three main OSs, macOS, Windows
and Linux.
- [x] Auto-update manual QA, from released version of component to new
version (see [tools/tuf/test](../tools/tuf/test/README.md)).
2024-06-27 13:26:20 -04:00

120 lines
2.7 KiB
Go

// based on github.com/kolide/launcher/pkg/osquery/tables
package tablehelpers
import (
"strings"
"github.com/osquery/osquery-go/plugin/table"
"github.com/rs/zerolog"
)
type constraintOptions struct {
allowedCharacters string
allowedValues []string
defaults []string
logger zerolog.Logger
}
type GetConstraintOpts func(*constraintOptions)
// WithLogger sets the logger to use
func WithLogger(logger zerolog.Logger) GetConstraintOpts {
return func(co *constraintOptions) {
co.logger = logger
}
}
// WithDefaults sets the defaults to use if no constraints were
// specified. Note that this does not apply if there were constraints,
// which were invalidated.
func WithDefaults(defaults ...string) GetConstraintOpts {
return func(co *constraintOptions) {
co.defaults = append(co.defaults, defaults...)
}
}
func WithAllowedCharacters(allowed string) GetConstraintOpts {
return func(co *constraintOptions) {
co.allowedCharacters = allowed
}
}
func WithAllowedValues(allowed []string) GetConstraintOpts {
return func(co *constraintOptions) {
co.allowedValues = allowed
}
}
// GetConstraints returns a []string of the constraint expressions on
// a column. It's meant for the common, simple, usecase of iterating over them.
func GetConstraints(queryContext table.QueryContext, columnName string, opts ...GetConstraintOpts) []string {
co := &constraintOptions{
logger: zerolog.Nop(),
}
for _, opt := range opts {
opt(co)
}
q, ok := queryContext.Constraints[columnName]
if !ok || len(q.Constraints) == 0 {
return co.defaults
}
constraintSet := make(map[string]struct{})
for _, c := range q.Constraints {
// No point in checking allowed characters, if we have an allowedValues. Just use it.
if len(co.allowedValues) == 0 && !co.OnlyAllowedCharacters(c.Expression) {
co.logger.Info().
Str("column", columnName).
Str("expression", c.Expression).
Msg("Disallowed character in expression")
continue
}
if len(co.allowedValues) > 0 {
skip := true
for _, v := range co.allowedValues {
if v == c.Expression {
skip = false
break
}
}
if skip {
co.logger.Info().
Str("column", columnName).
Str("expression", c.Expression).
Msg("Disallowed value in expression")
continue
}
}
// empty struct is less ram than bool would be
constraintSet[c.Expression] = struct{}{}
}
constraints := make([]string, len(constraintSet))
i := 0
for key := range constraintSet {
constraints[i] = key
i++
}
return constraints
}
func (co *constraintOptions) OnlyAllowedCharacters(input string) bool {
if co.allowedCharacters == "" {
return true
}
for _, char := range input {
if !strings.ContainsRune(co.allowedCharacters, char) {
return false
}
}
return true
}