...

Source file src/github.com/linkerd/linkerd2/viz/pkg/jsonpath/jsonpath.go

Documentation: github.com/linkerd/linkerd2/viz/pkg/jsonpath

     1  package jsonpath
     2  
     3  import (
     4  	"encoding/json"
     5  	"errors"
     6  	"fmt"
     7  	"regexp"
     8  	"strings"
     9  
    10  	"k8s.io/client-go/util/jsonpath"
    11  )
    12  
    13  var jsonRegexp = regexp.MustCompile(`^\{\.?([^{}]+)\}$|^\.?([^{}]+)$`)
    14  
    15  func GetJsonPathFlagVal(flagVal string) (string, error) {
    16  	val := strings.Split(flagVal, "=")
    17  	if len(val) != 2 || len(val) == 2 && val[1] == "" {
    18  		return "", errors.New("{\"error jsonpath\": \"jsonpath filter not found\"}")
    19  	}
    20  
    21  	return val[1], nil
    22  
    23  }
    24  
    25  // GetFormatedJSONPathExpression get jsonpath filter from flag and attempts to be flexible with JSONPath expressions, it accepts:
    26  //   - metadata.name (no leading '.' or curly braces '{...}'
    27  //   - {metadata.name} (no leading '.')
    28  //   - .metadata.name (no curly braces '{...}')
    29  //   - {.metadata.name} (complete expression)
    30  //
    31  // And transforms them all into a valid jsonpath expression:
    32  //
    33  //	{.metadata.name}
    34  func GetFormatedJSONPathExpression(pathExpression string) (string, error) {
    35  	if len(pathExpression) == 0 {
    36  		return pathExpression, nil
    37  	}
    38  	submatches := jsonRegexp.FindStringSubmatch(pathExpression)
    39  	if submatches == nil {
    40  		return "", errors.New("{\"error jsonpath\": \"unexpected path string, expected a 'name1.name2' or '.name1.name2' or '{name1.name2}' or '{.name1.name2}'\"}")
    41  	}
    42  	if len(submatches) != 3 {
    43  		return "", fmt.Errorf("{\"error jsonpath\":\"unexpected submatch list: %v\"", submatches)
    44  	}
    45  	var fieldSpec string
    46  	if len(submatches[1]) != 0 {
    47  		fieldSpec = submatches[1]
    48  	} else {
    49  		fieldSpec = submatches[2]
    50  	}
    51  	return fmt.Sprintf("{.%s}", fieldSpec), nil
    52  }
    53  
    54  func GetJsonFilteredByJPath(event interface{}, jsonPath string) ([]string, error) {
    55  	fields, err := GetFormatedJSONPathExpression(jsonPath)
    56  	if err != nil {
    57  		return []string{}, err
    58  	}
    59  
    60  	j := jsonpath.New("EventParser")
    61  	if err := j.Parse(fields); err != nil {
    62  		return []string{}, fmt.Errorf("{\"error parsing jsonpath\":\" %s\" }", err.Error())
    63  	}
    64  
    65  	results, err := j.FindResults(event)
    66  	if err != nil {
    67  		return []string{}, fmt.Errorf("{\"error jsonpath\":\" %s\" }", err.Error())
    68  	}
    69  
    70  	filteredEvent := []string{}
    71  	if len(results) == 0 || len(results[0]) == 0 {
    72  		return filteredEvent, errors.New("{\"error filtering JSON\": \"couldn't find any results matching with jsonpath filter\"}")
    73  	}
    74  
    75  	for _, result := range results {
    76  		for _, match := range result {
    77  			e, err := json.MarshalIndent(match.Interface(), "", "  ")
    78  			if err != nil {
    79  				return []string{}, fmt.Errorf("{\"error marshalling JSON\": \"%s\"}", err.Error())
    80  			}
    81  			filteredEvent = append(filteredEvent, string(e))
    82  		}
    83  	}
    84  
    85  	return filteredEvent, nil
    86  }
    87  

View as plain text