2021-04-17 02:17:00 +03:00
package jmespath
import (
2022-09-28 19:15:39 +01:00
"bytes"
2023-04-03 17:10:47 +05:30
"crypto/rand"
2023-04-14 15:06:38 +05:30
"crypto/rsa"
2024-01-05 16:14:26 +05:30
"crypto/sha256"
2022-09-28 19:15:39 +01:00
"crypto/x509"
"encoding/asn1"
2021-10-14 19:46:06 +01:00
"encoding/base64"
2024-01-05 16:14:26 +05:30
"encoding/hex"
2022-01-10 21:42:02 +00:00
"encoding/json"
2022-09-28 19:15:39 +01:00
"encoding/pem"
2021-04-17 02:17:00 +03:00
"errors"
"fmt"
2023-07-04 01:01:54 +05:30
"math"
2023-11-21 12:17:26 +08:00
"net"
"net/url"
2021-12-06 19:10:34 +08:00
"path/filepath"
2021-04-17 02:17:00 +03:00
"reflect"
"regexp"
2022-05-04 06:33:24 -04:00
"sort"
2021-04-17 02:17:00 +03:00
"strconv"
"strings"
2021-12-17 02:52:52 -05:00
trunc "github.com/aquilax/truncate"
2021-12-21 21:42:35 +05:30
"github.com/blang/semver/v4"
2023-07-07 12:22:26 +02:00
gojmespath "github.com/kyverno/go-jmespath"
2023-10-30 00:59:53 +01:00
"github.com/kyverno/kyverno/ext/wildcard"
2023-04-13 18:13:40 +02:00
"github.com/kyverno/kyverno/pkg/config"
imageutils "github.com/kyverno/kyverno/pkg/utils/image"
2022-09-07 21:52:30 +05:30
regen "github.com/zach-klippenstein/goregen"
2022-09-28 19:15:39 +01:00
"golang.org/x/crypto/cryptobyte"
cryptobyte_asn1 "golang.org/x/crypto/cryptobyte/asn1"
2022-01-17 13:41:08 +00:00
"sigs.k8s.io/yaml"
2021-04-17 02:17:00 +03:00
)
2022-09-28 19:15:39 +01:00
type PublicKey struct {
N string
E int
}
2021-04-17 02:17:00 +03:00
// function names
var (
compare = "compare"
equalFold = "equal_fold"
replace = "replace"
replaceAll = "replace_all"
toUpper = "to_upper"
toLower = "to_lower"
trim = "trim"
2023-02-08 06:54:59 -05:00
trimPrefix = "trim_prefix"
2021-04-17 02:17:00 +03:00
split = "split"
regexReplaceAll = "regex_replace_all"
regexReplaceAllLiteral = "regex_replace_all_literal"
regexMatch = "regex_match"
2021-11-29 17:13:07 +01:00
patternMatch = "pattern_match"
2021-05-04 18:28:30 +02:00
labelMatch = "label_match"
2023-03-16 18:22:26 +05:30
toBoolean = "to_boolean"
2021-09-23 03:10:45 +05:30
add = "add"
2023-03-23 14:29:05 +05:30
sum = "sum"
2021-09-23 03:10:45 +05:30
subtract = "subtract"
multiply = "multiply"
divide = "divide"
modulo = "modulo"
2023-07-04 01:01:54 +05:30
round = "round"
2021-10-14 19:46:06 +01:00
base64Decode = "base64_decode"
base64Encode = "base64_encode"
2021-12-06 19:10:34 +08:00
pathCanonicalize = "path_canonicalize"
2021-12-17 02:52:52 -05:00
truncate = "truncate"
2021-12-21 21:42:35 +05:30
semverCompare = "semver_compare"
2022-01-10 21:42:02 +00:00
parseJson = "parse_json"
2022-01-17 13:41:08 +00:00
parseYAML = "parse_yaml"
2023-06-19 15:45:13 +02:00
lookup = "lookup"
2022-05-04 06:33:24 -04:00
items = "items"
2022-05-07 13:05:04 +01:00
objectFromLists = "object_from_lists"
2022-09-07 21:52:30 +05:30
random = "random"
2022-09-28 19:15:39 +01:00
x509_decode = "x509_decode"
2023-04-13 18:13:40 +02:00
imageNormalize = "image_normalize"
2023-11-21 12:17:26 +08:00
isExternalURL = "is_external_url"
2024-01-05 16:14:26 +05:30
SHA256 = "sha256"
2021-04-17 02:17:00 +03:00
)
2023-04-13 18:13:40 +02:00
func GetFunctions ( configuration config . Configuration ) [ ] FunctionEntry {
2023-02-06 07:27:27 +01:00
return [ ] FunctionEntry { {
FunctionEntry : gojmespath . FunctionEntry {
Name : compare ,
Arguments : [ ] argSpec {
{ Types : [ ] jpType { jpString } } ,
{ Types : [ ] jpType { jpString } } ,
} ,
Handler : jpfCompare ,
} ,
ReturnType : [ ] jpType { jpNumber } ,
Note : "compares two strings lexicographically" ,
} , {
FunctionEntry : gojmespath . FunctionEntry {
Name : equalFold ,
Arguments : [ ] argSpec {
{ Types : [ ] jpType { jpString } } ,
{ Types : [ ] jpType { jpString } } ,
} ,
Handler : jpfEqualFold ,
} ,
ReturnType : [ ] jpType { jpBool } ,
Note : "allows comparing two strings for equivalency where the only differences are letter cases" ,
} , {
FunctionEntry : gojmespath . FunctionEntry {
Name : replace ,
Arguments : [ ] argSpec {
{ Types : [ ] jpType { jpString } } ,
{ Types : [ ] jpType { jpString } } ,
{ Types : [ ] jpType { jpString } } ,
{ Types : [ ] jpType { jpNumber } } ,
} ,
Handler : jpfReplace ,
} ,
ReturnType : [ ] jpType { jpString } ,
Note : "replaces a specified number of instances of the source string with the replacement string in a parent " ,
} , {
FunctionEntry : gojmespath . FunctionEntry {
Name : replaceAll ,
Arguments : [ ] argSpec {
{ Types : [ ] jpType { jpString } } ,
{ Types : [ ] jpType { jpString } } ,
{ Types : [ ] jpType { jpString } } ,
} ,
Handler : jpfReplaceAll ,
} ,
ReturnType : [ ] jpType { jpString } ,
Note : "replace all instances of one string with another in an overall parent string" ,
} , {
FunctionEntry : gojmespath . FunctionEntry {
Name : toUpper ,
Arguments : [ ] argSpec {
{ Types : [ ] jpType { jpString } } ,
} ,
Handler : jpfToUpper ,
} ,
ReturnType : [ ] jpType { jpString } ,
Note : "takes in a string and outputs the same string with all upper-case letters" ,
} , {
FunctionEntry : gojmespath . FunctionEntry {
Name : toLower ,
Arguments : [ ] argSpec {
{ Types : [ ] jpType { jpString } } ,
} ,
Handler : jpfToLower ,
} ,
ReturnType : [ ] jpType { jpString } ,
Note : "takes in a string and outputs the same string with all lower-case letters" ,
} , {
FunctionEntry : gojmespath . FunctionEntry {
Name : trim ,
Arguments : [ ] argSpec {
{ Types : [ ] jpType { jpString } } ,
{ Types : [ ] jpType { jpString } } ,
} ,
Handler : jpfTrim ,
} ,
ReturnType : [ ] jpType { jpString } ,
Note : "trims both ends of the source string by characters appearing in the second string" ,
2023-02-08 06:54:59 -05:00
} , {
FunctionEntry : gojmespath . FunctionEntry {
Name : trimPrefix ,
Arguments : [ ] argSpec {
{ Types : [ ] jpType { jpString } } ,
{ Types : [ ] jpType { jpString } } ,
} ,
Handler : jpfTrimPrefix ,
} ,
ReturnType : [ ] jpType { jpString } ,
Note : "trims the second string prefix from the first string if the first string starts with the prefix" ,
2023-02-06 07:27:27 +01:00
} , {
FunctionEntry : gojmespath . FunctionEntry {
Name : split ,
Arguments : [ ] argSpec {
{ Types : [ ] jpType { jpString } } ,
{ Types : [ ] jpType { jpString } } ,
} ,
Handler : jpfSplit ,
} ,
ReturnType : [ ] jpType { jpArrayString } ,
Note : "splits the first string when the second string is found and converts it into an array " ,
} , {
FunctionEntry : gojmespath . FunctionEntry {
Name : regexReplaceAll ,
Arguments : [ ] argSpec {
{ Types : [ ] jpType { jpString } } ,
{ Types : [ ] jpType { jpString , jpNumber } } ,
{ Types : [ ] jpType { jpString , jpNumber } } ,
} ,
Handler : jpRegexReplaceAll ,
} ,
ReturnType : [ ] jpType { jpString } ,
Note : "converts all parameters to string" ,
} , {
FunctionEntry : gojmespath . FunctionEntry {
Name : regexReplaceAllLiteral ,
Arguments : [ ] argSpec {
{ Types : [ ] jpType { jpString } } ,
{ Types : [ ] jpType { jpString , jpNumber } } ,
{ Types : [ ] jpType { jpString , jpNumber } } ,
} ,
Handler : jpRegexReplaceAllLiteral ,
} ,
ReturnType : [ ] jpType { jpString } ,
Note : "converts all parameters to string" ,
} , {
FunctionEntry : gojmespath . FunctionEntry {
Name : regexMatch ,
Arguments : [ ] argSpec {
{ Types : [ ] jpType { jpString } } ,
{ Types : [ ] jpType { jpString , jpNumber } } ,
} ,
Handler : jpRegexMatch ,
} ,
ReturnType : [ ] jpType { jpBool } ,
Note : "first string is the regular exression which is compared with second input which can be a number or string" ,
} , {
FunctionEntry : gojmespath . FunctionEntry {
Name : patternMatch ,
Arguments : [ ] argSpec {
{ Types : [ ] jpType { jpString } } ,
{ Types : [ ] jpType { jpString , jpNumber } } ,
} ,
Handler : jpPatternMatch ,
} ,
ReturnType : [ ] jpType { jpBool } ,
Note : "'*' matches zero or more alphanumeric characters, '?' matches a single alphanumeric character" ,
} , {
// Validates if label (param1) would match pod/host/etc labels (param2)
FunctionEntry : gojmespath . FunctionEntry {
Name : labelMatch ,
Arguments : [ ] argSpec {
{ Types : [ ] jpType { jpObject } } ,
{ Types : [ ] jpType { jpObject } } ,
} ,
Handler : jpLabelMatch ,
} ,
ReturnType : [ ] jpType { jpBool } ,
Note : "object arguments must be enclosed in backticks; ex. `{{request.object.spec.template.metadata.labels}}`" ,
2023-03-16 18:22:26 +05:30
} , {
FunctionEntry : gojmespath . FunctionEntry {
Name : toBoolean ,
Arguments : [ ] argSpec {
{ Types : [ ] jpType { jpString } } ,
} ,
Handler : jpToBoolean ,
} ,
ReturnType : [ ] jpType { jpBool } ,
Note : "It returns true or false for any string, such as 'True', 'TruE', 'False', 'FAlse', 'faLSE', etc." ,
2023-02-06 07:27:27 +01:00
} , {
FunctionEntry : gojmespath . FunctionEntry {
Name : add ,
Arguments : [ ] argSpec {
{ Types : [ ] jpType { jpAny } } ,
{ Types : [ ] jpType { jpAny } } ,
} ,
Handler : jpAdd ,
} ,
ReturnType : [ ] jpType { jpAny } ,
Note : "does arithmetic addition of two specified values of numbers, quantities, and durations" ,
2023-03-23 14:29:05 +05:30
} , {
FunctionEntry : gojmespath . FunctionEntry {
Name : sum ,
Arguments : [ ] argSpec {
{ Types : [ ] jpType { jpArray } } ,
} ,
Handler : jpSum ,
} ,
ReturnType : [ ] jpType { jpAny } ,
Note : "does arithmetic addition of specified array of values of numbers, quantities, and durations" ,
2023-02-06 07:27:27 +01:00
} , {
FunctionEntry : gojmespath . FunctionEntry {
Name : subtract ,
Arguments : [ ] argSpec {
{ Types : [ ] jpType { jpAny } } ,
{ Types : [ ] jpType { jpAny } } ,
} ,
Handler : jpSubtract ,
} ,
ReturnType : [ ] jpType { jpAny } ,
Note : "does arithmetic subtraction of two specified values of numbers, quantities, and durations" ,
} , {
FunctionEntry : gojmespath . FunctionEntry {
Name : multiply ,
Arguments : [ ] argSpec {
{ Types : [ ] jpType { jpAny } } ,
{ Types : [ ] jpType { jpAny } } ,
} ,
Handler : jpMultiply ,
} ,
ReturnType : [ ] jpType { jpAny } ,
Note : "does arithmetic multiplication of two specified values of numbers, quantities, and durations" ,
} , {
FunctionEntry : gojmespath . FunctionEntry {
Name : divide ,
Arguments : [ ] argSpec {
{ Types : [ ] jpType { jpAny } } ,
{ Types : [ ] jpType { jpAny } } ,
} ,
Handler : jpDivide ,
} ,
ReturnType : [ ] jpType { jpAny } ,
Note : "divisor must be non zero" ,
} , {
FunctionEntry : gojmespath . FunctionEntry {
Name : modulo ,
Arguments : [ ] argSpec {
{ Types : [ ] jpType { jpAny } } ,
{ Types : [ ] jpType { jpAny } } ,
} ,
Handler : jpModulo ,
} ,
ReturnType : [ ] jpType { jpAny } ,
Note : "divisor must be non-zero, arguments must be integers" ,
2023-07-04 01:01:54 +05:30
} , {
FunctionEntry : gojmespath . FunctionEntry {
Name : round ,
Arguments : [ ] argSpec {
{ Types : [ ] jpType { jpNumber } } ,
{ Types : [ ] jpType { jpNumber } } ,
} ,
Handler : jpRound ,
} ,
ReturnType : [ ] jpType { jpNumber } ,
Note : "does roundoff to upto the given decimal places" ,
2023-02-06 07:27:27 +01:00
} , {
FunctionEntry : gojmespath . FunctionEntry {
Name : base64Decode ,
Arguments : [ ] argSpec {
{ Types : [ ] jpType { jpString } } ,
} ,
Handler : jpBase64Decode ,
} ,
ReturnType : [ ] jpType { jpString } ,
Note : "decodes a base 64 string" ,
} , {
FunctionEntry : gojmespath . FunctionEntry {
Name : base64Encode ,
Arguments : [ ] argSpec {
{ Types : [ ] jpType { jpString } } ,
} ,
Handler : jpBase64Encode ,
} ,
ReturnType : [ ] jpType { jpString } ,
Note : "encodes a regular, plaintext and unencoded string to base64" ,
} , {
FunctionEntry : gojmespath . FunctionEntry {
Name : timeSince ,
Arguments : [ ] argSpec {
{ Types : [ ] jpType { jpString } } ,
{ Types : [ ] jpType { jpString } } ,
{ Types : [ ] jpType { jpString } } ,
} ,
Handler : jpTimeSince ,
} ,
ReturnType : [ ] jpType { jpString } ,
Note : "calculate the difference between a start and end period of time where the end may either be a static definition or the then-current time" ,
} , {
FunctionEntry : gojmespath . FunctionEntry {
Name : timeNow ,
Handler : jpTimeNow ,
} ,
ReturnType : [ ] jpType { jpString } ,
Note : "returns current time in RFC 3339 format" ,
} , {
FunctionEntry : gojmespath . FunctionEntry {
Name : timeNowUtc ,
Handler : jpTimeNowUtc ,
} ,
ReturnType : [ ] jpType { jpString } ,
Note : "returns current UTC time in RFC 3339 format" ,
} , {
FunctionEntry : gojmespath . FunctionEntry {
Name : pathCanonicalize ,
Arguments : [ ] argSpec {
{ Types : [ ] jpType { jpString } } ,
} ,
Handler : jpPathCanonicalize ,
} ,
ReturnType : [ ] jpType { jpString } ,
Note : "normalizes or canonicalizes a given path by removing excess slashes" ,
} , {
FunctionEntry : gojmespath . FunctionEntry {
Name : truncate ,
Arguments : [ ] argSpec {
{ Types : [ ] jpType { jpString } } ,
{ Types : [ ] jpType { jpNumber } } ,
} ,
Handler : jpTruncate ,
} ,
ReturnType : [ ] jpType { jpString } ,
Note : "length argument must be enclosed in backticks; ex. \"{{request.object.metadata.name | truncate(@, `9`)}}\"" ,
} , {
FunctionEntry : gojmespath . FunctionEntry {
Name : semverCompare ,
Arguments : [ ] argSpec {
{ Types : [ ] jpType { jpString } } ,
{ Types : [ ] jpType { jpString } } ,
} ,
Handler : jpSemverCompare ,
} ,
ReturnType : [ ] jpType { jpBool } ,
Note : "compares two strings which comply with the semantic versioning schema and outputs a boolean response as to the position of the second relative to the first" ,
} , {
FunctionEntry : gojmespath . FunctionEntry {
Name : parseJson ,
Arguments : [ ] argSpec {
{ Types : [ ] jpType { jpString } } ,
} ,
Handler : jpParseJson ,
} ,
ReturnType : [ ] jpType { jpAny } ,
Note : "decodes a valid JSON encoded string to the appropriate type. Opposite of `to_string` function" ,
} , {
FunctionEntry : gojmespath . FunctionEntry {
Name : parseYAML ,
Arguments : [ ] argSpec {
{ Types : [ ] jpType { jpString } } ,
} ,
Handler : jpParseYAML ,
} ,
ReturnType : [ ] jpType { jpAny } ,
Note : "decodes a valid YAML encoded string to the appropriate type provided it can be represented as JSON" ,
2023-06-19 15:45:13 +02:00
} , {
FunctionEntry : gojmespath . FunctionEntry {
Name : lookup ,
Arguments : [ ] argSpec {
{ Types : [ ] jpType { jpObject , jpArray } } ,
{ Types : [ ] jpType { jpString , jpNumber } } ,
} ,
Handler : jpLookup ,
} ,
ReturnType : [ ] jpType { jpAny } ,
Note : "returns the value corresponding to the given key/index in the given object/array" ,
2023-02-06 07:27:27 +01:00
} , {
FunctionEntry : gojmespath . FunctionEntry {
Name : items ,
Arguments : [ ] argSpec {
{ Types : [ ] jpType { jpObject , jpArray } } ,
{ Types : [ ] jpType { jpString } } ,
{ Types : [ ] jpType { jpString } } ,
} ,
Handler : jpItems ,
} ,
ReturnType : [ ] jpType { jpArray } ,
Note : "converts a map or array to an array of objects where each key:value is an item in the array" ,
} , {
FunctionEntry : gojmespath . FunctionEntry {
Name : objectFromLists ,
Arguments : [ ] argSpec {
{ Types : [ ] jpType { jpArray } } ,
{ Types : [ ] jpType { jpArray } } ,
} ,
Handler : jpObjectFromLists ,
} ,
ReturnType : [ ] jpType { jpObject } ,
Note : "converts a pair of lists containing keys and values to an object" ,
} , {
FunctionEntry : gojmespath . FunctionEntry {
Name : random ,
Arguments : [ ] argSpec {
{ Types : [ ] jpType { jpString } } ,
} ,
Handler : jpRandom ,
} ,
ReturnType : [ ] jpType { jpString } ,
Note : "Generates a random sequence of characters" ,
} , {
FunctionEntry : gojmespath . FunctionEntry {
Name : x509_decode ,
Arguments : [ ] argSpec {
{ Types : [ ] jpType { jpString } } ,
} ,
Handler : jpX509Decode ,
} ,
ReturnType : [ ] jpType { jpObject } ,
Note : "decodes an x.509 certificate to an object. you may also use this in conjunction with `base64_decode` jmespath function to decode a base64-encoded certificate" ,
} , {
FunctionEntry : gojmespath . FunctionEntry {
Name : timeToCron ,
Arguments : [ ] argSpec {
{ Types : [ ] jpType { jpString } } ,
} ,
Handler : jpTimeToCron ,
} ,
ReturnType : [ ] jpType { jpString } ,
Note : "converts a time (RFC 3339) to a cron expression (string)." ,
} , {
FunctionEntry : gojmespath . FunctionEntry {
Name : timeAdd ,
Arguments : [ ] argSpec {
{ Types : [ ] jpType { jpString } } ,
{ Types : [ ] jpType { jpString } } ,
} ,
Handler : jpTimeAdd ,
} ,
ReturnType : [ ] jpType { jpString } ,
Note : "adds duration (second string) to a time value (first string)" ,
} , {
FunctionEntry : gojmespath . FunctionEntry {
Name : timeParse ,
Arguments : [ ] argSpec {
{ Types : [ ] jpType { jpString } } ,
{ Types : [ ] jpType { jpString } } ,
} ,
Handler : jpTimeParse ,
} ,
ReturnType : [ ] jpType { jpString } ,
Note : "changes a time value of a given layout to RFC 3339" ,
} , {
FunctionEntry : gojmespath . FunctionEntry {
Name : timeUtc ,
Arguments : [ ] argSpec {
{ Types : [ ] jpType { jpString } } ,
} ,
Handler : jpTimeUtc ,
} ,
ReturnType : [ ] jpType { jpString } ,
Note : "calcutes time in UTC from a given time in RFC 3339 format" ,
} , {
FunctionEntry : gojmespath . FunctionEntry {
Name : timeDiff ,
Arguments : [ ] argSpec {
{ Types : [ ] jpType { jpString } } ,
{ Types : [ ] jpType { jpString } } ,
} ,
Handler : jpTimeDiff ,
} ,
ReturnType : [ ] jpType { jpString } ,
Note : "calculate the difference between a start and end date in RFC3339 format" ,
} , {
FunctionEntry : gojmespath . FunctionEntry {
Name : timeBefore ,
Arguments : [ ] argSpec {
{ Types : [ ] jpType { jpString } } ,
{ Types : [ ] jpType { jpString } } ,
} ,
Handler : jpTimeBefore ,
} ,
ReturnType : [ ] jpType { jpBool } ,
Note : "checks if a time is before another time, both in RFC3339 format" ,
} , {
FunctionEntry : gojmespath . FunctionEntry {
Name : timeAfter ,
Arguments : [ ] argSpec {
{ Types : [ ] jpType { jpString } } ,
{ Types : [ ] jpType { jpString } } ,
} ,
Handler : jpTimeAfter ,
} ,
ReturnType : [ ] jpType { jpBool } ,
Note : "checks if a time is after another time, both in RFC3339 format" ,
} , {
FunctionEntry : gojmespath . FunctionEntry {
Name : timeBetween ,
Arguments : [ ] argSpec {
{ Types : [ ] jpType { jpString } } ,
{ Types : [ ] jpType { jpString } } ,
{ Types : [ ] jpType { jpString } } ,
} ,
Handler : jpTimeBetween ,
} ,
ReturnType : [ ] jpType { jpBool } ,
Note : "checks if a time is between a start and end time, all in RFC3339 format" ,
} , {
FunctionEntry : gojmespath . FunctionEntry {
Name : timeTruncate ,
Arguments : [ ] argSpec {
{ Types : [ ] jpType { jpString } } ,
{ Types : [ ] jpType { jpString } } ,
} ,
Handler : jpTimeTruncate ,
} ,
ReturnType : [ ] jpType { jpString } ,
Note : "returns the result of rounding time down to a multiple of duration" ,
2023-04-13 18:13:40 +02:00
} , {
FunctionEntry : gojmespath . FunctionEntry {
Name : imageNormalize ,
Arguments : [ ] argSpec {
{ Types : [ ] jpType { jpString } } ,
} ,
Handler : jpImageNormalize ( configuration ) ,
} ,
ReturnType : [ ] jpType { jpString } ,
Note : "normalizes an image reference" ,
2023-11-21 12:17:26 +08:00
} , {
FunctionEntry : gojmespath . FunctionEntry {
Name : isExternalURL ,
Arguments : [ ] argSpec {
{ Types : [ ] jpType { jpString } } ,
} ,
Handler : jpIsExternalURL ,
} ,
ReturnType : [ ] jpType { jpBool } ,
Note : "determine if a URL points to an external network address" ,
2024-01-05 16:14:26 +05:30
} , {
FunctionEntry : gojmespath . FunctionEntry {
Name : SHA256 ,
Arguments : [ ] argSpec {
{ Types : [ ] jpType { jpString } } ,
} ,
Handler : jpSha256 ,
} ,
ReturnType : [ ] jpType { jpString } ,
Note : "generate unique resources name if length exceeds the limit" ,
2023-02-06 07:27:27 +01:00
} }
2021-04-17 02:17:00 +03:00
}
func jpfCompare ( arguments [ ] interface { } ) ( interface { } , error ) {
2023-02-03 06:37:31 +01:00
if a , err := validateArg ( compare , arguments , 0 , reflect . String ) ; err != nil {
2021-04-17 02:17:00 +03:00
return nil , err
2023-02-03 06:37:31 +01:00
} else if b , err := validateArg ( compare , arguments , 1 , reflect . String ) ; err != nil {
2021-04-17 02:17:00 +03:00
return nil , err
2023-02-03 06:37:31 +01:00
} else {
return strings . Compare ( a . String ( ) , b . String ( ) ) , nil
2021-04-17 02:17:00 +03:00
}
}
func jpfEqualFold ( arguments [ ] interface { } ) ( interface { } , error ) {
2023-02-03 06:37:31 +01:00
if a , err := validateArg ( equalFold , arguments , 0 , reflect . String ) ; err != nil {
2021-04-17 02:17:00 +03:00
return nil , err
2023-02-03 06:37:31 +01:00
} else if b , err := validateArg ( equalFold , arguments , 1 , reflect . String ) ; err != nil {
2021-04-17 02:17:00 +03:00
return nil , err
2023-02-03 06:37:31 +01:00
} else {
return strings . EqualFold ( a . String ( ) , b . String ( ) ) , nil
2021-04-17 02:17:00 +03:00
}
}
func jpfReplace ( arguments [ ] interface { } ) ( interface { } , error ) {
2023-02-03 06:37:31 +01:00
if str , err := validateArg ( replace , arguments , 0 , reflect . String ) ; err != nil {
2021-04-17 02:17:00 +03:00
return nil , err
2023-02-03 06:37:31 +01:00
} else if old , err := validateArg ( replace , arguments , 1 , reflect . String ) ; err != nil {
2021-04-17 02:17:00 +03:00
return nil , err
2023-02-03 06:37:31 +01:00
} else if new , err := validateArg ( replace , arguments , 2 , reflect . String ) ; err != nil {
2021-04-17 02:17:00 +03:00
return nil , err
2023-02-03 06:37:31 +01:00
} else if n , err := validateArg ( replace , arguments , 3 , reflect . Float64 ) ; err != nil {
2021-04-17 02:17:00 +03:00
return nil , err
2023-02-03 06:37:31 +01:00
} else {
return strings . Replace ( str . String ( ) , old . String ( ) , new . String ( ) , int ( n . Float ( ) ) ) , nil
2021-04-17 02:17:00 +03:00
}
}
func jpfReplaceAll ( arguments [ ] interface { } ) ( interface { } , error ) {
2023-02-06 07:27:27 +01:00
if str , err := validateArg ( replaceAll , arguments , 0 , reflect . String ) ; err != nil {
2021-04-17 02:17:00 +03:00
return nil , err
2023-02-06 07:27:27 +01:00
} else if old , err := validateArg ( replaceAll , arguments , 1 , reflect . String ) ; err != nil {
2021-04-17 02:17:00 +03:00
return nil , err
2023-02-06 07:27:27 +01:00
} else if new , err := validateArg ( replaceAll , arguments , 2 , reflect . String ) ; err != nil {
2021-04-17 02:17:00 +03:00
return nil , err
2023-02-06 07:27:27 +01:00
} else {
return strings . ReplaceAll ( str . String ( ) , old . String ( ) , new . String ( ) ) , nil
2021-04-17 02:17:00 +03:00
}
}
func jpfToUpper ( arguments [ ] interface { } ) ( interface { } , error ) {
2023-02-06 07:27:27 +01:00
if str , err := validateArg ( toUpper , arguments , 0 , reflect . String ) ; err != nil {
2021-04-17 02:17:00 +03:00
return nil , err
2023-02-06 07:27:27 +01:00
} else {
return strings . ToUpper ( str . String ( ) ) , nil
2021-04-17 02:17:00 +03:00
}
}
func jpfToLower ( arguments [ ] interface { } ) ( interface { } , error ) {
2023-02-06 07:27:27 +01:00
if str , err := validateArg ( toLower , arguments , 0 , reflect . String ) ; err != nil {
2021-04-17 02:17:00 +03:00
return nil , err
2023-02-06 07:27:27 +01:00
} else {
return strings . ToLower ( str . String ( ) ) , nil
2021-04-17 02:17:00 +03:00
}
}
func jpfTrim ( arguments [ ] interface { } ) ( interface { } , error ) {
var err error
str , err := validateArg ( trim , arguments , 0 , reflect . String )
if err != nil {
return nil , err
}
cutset , err := validateArg ( trim , arguments , 1 , reflect . String )
if err != nil {
return nil , err
}
return strings . Trim ( str . String ( ) , cutset . String ( ) ) , nil
}
2023-02-08 06:54:59 -05:00
func jpfTrimPrefix ( arguments [ ] interface { } ) ( interface { } , error ) {
var err error
str , err := validateArg ( trimPrefix , arguments , 0 , reflect . String )
if err != nil {
return nil , err
}
prefix , err := validateArg ( trimPrefix , arguments , 1 , reflect . String )
if err != nil {
return nil , err
}
return strings . TrimPrefix ( str . String ( ) , prefix . String ( ) ) , nil
}
2021-04-17 02:17:00 +03:00
func jpfSplit ( arguments [ ] interface { } ) ( interface { } , error ) {
var err error
str , err := validateArg ( split , arguments , 0 , reflect . String )
if err != nil {
return nil , err
}
sep , err := validateArg ( split , arguments , 1 , reflect . String )
if err != nil {
return nil , err
}
2021-10-29 11:26:18 +05:30
split := strings . Split ( str . String ( ) , sep . String ( ) )
arr := make ( [ ] interface { } , len ( split ) )
for i , v := range split {
arr [ i ] = v
}
return arr , nil
2021-04-17 02:17:00 +03:00
}
func jpRegexReplaceAll ( arguments [ ] interface { } ) ( interface { } , error ) {
var err error
regex , err := validateArg ( regexReplaceAll , arguments , 0 , reflect . String )
if err != nil {
return nil , err
}
src , err := ifaceToString ( arguments [ 1 ] )
if err != nil {
2023-02-06 15:13:44 +01:00
return nil , formatError ( invalidArgumentTypeError , regexReplaceAll , 2 , "String or Real" )
2021-04-17 02:17:00 +03:00
}
repl , err := ifaceToString ( arguments [ 2 ] )
if err != nil {
2023-02-06 15:13:44 +01:00
return nil , formatError ( invalidArgumentTypeError , regexReplaceAll , 3 , "String or Real" )
2021-04-17 02:17:00 +03:00
}
reg , err := regexp . Compile ( regex . String ( ) )
if err != nil {
2023-02-06 15:13:44 +01:00
return nil , formatError ( genericError , regexReplaceAll , err . Error ( ) )
2021-04-17 02:17:00 +03:00
}
return string ( reg . ReplaceAll ( [ ] byte ( src ) , [ ] byte ( repl ) ) ) , nil
}
func jpRegexReplaceAllLiteral ( arguments [ ] interface { } ) ( interface { } , error ) {
var err error
regex , err := validateArg ( regexReplaceAllLiteral , arguments , 0 , reflect . String )
if err != nil {
return nil , err
}
src , err := ifaceToString ( arguments [ 1 ] )
if err != nil {
2023-02-06 15:13:44 +01:00
return nil , formatError ( invalidArgumentTypeError , regexReplaceAllLiteral , 2 , "String or Real" )
2021-04-17 02:17:00 +03:00
}
repl , err := ifaceToString ( arguments [ 2 ] )
if err != nil {
2023-02-06 15:13:44 +01:00
return nil , formatError ( invalidArgumentTypeError , regexReplaceAllLiteral , 3 , "String or Real" )
2021-04-17 02:17:00 +03:00
}
reg , err := regexp . Compile ( regex . String ( ) )
if err != nil {
2023-02-06 15:13:44 +01:00
return nil , formatError ( genericError , regexReplaceAllLiteral , err . Error ( ) )
2021-04-17 02:17:00 +03:00
}
return string ( reg . ReplaceAllLiteral ( [ ] byte ( src ) , [ ] byte ( repl ) ) ) , nil
}
func jpRegexMatch ( arguments [ ] interface { } ) ( interface { } , error ) {
var err error
regex , err := validateArg ( regexMatch , arguments , 0 , reflect . String )
if err != nil {
return nil , err
}
src , err := ifaceToString ( arguments [ 1 ] )
if err != nil {
2023-02-06 15:13:44 +01:00
return nil , formatError ( invalidArgumentTypeError , regexMatch , 2 , "String or Real" )
2021-04-17 02:17:00 +03:00
}
return regexp . Match ( regex . String ( ) , [ ] byte ( src ) )
}
2021-11-29 17:13:07 +01:00
func jpPatternMatch ( arguments [ ] interface { } ) ( interface { } , error ) {
pattern , err := validateArg ( regexMatch , arguments , 0 , reflect . String )
if err != nil {
return nil , err
}
src , err := ifaceToString ( arguments [ 1 ] )
if err != nil {
2023-02-06 15:13:44 +01:00
return nil , formatError ( invalidArgumentTypeError , regexMatch , 2 , "String or Real" )
2021-11-29 17:13:07 +01:00
}
return wildcard . Match ( pattern . String ( ) , src ) , nil
}
2021-05-04 18:28:30 +02:00
func jpLabelMatch ( arguments [ ] interface { } ) ( interface { } , error ) {
labelMap , ok := arguments [ 0 ] . ( map [ string ] interface { } )
if ! ok {
2023-02-06 15:13:44 +01:00
return nil , formatError ( invalidArgumentTypeError , labelMatch , 0 , "Object" )
2021-05-04 18:28:30 +02:00
}
matchMap , ok := arguments [ 1 ] . ( map [ string ] interface { } )
if ! ok {
2023-02-06 15:13:44 +01:00
return nil , formatError ( invalidArgumentTypeError , labelMatch , 1 , "Object" )
2021-05-04 18:28:30 +02:00
}
for key , value := range labelMap {
if val , ok := matchMap [ key ] ; ! ok || val != value {
return false , nil
}
}
return true , nil
}
2023-03-16 18:22:26 +05:30
func jpToBoolean ( arguments [ ] interface { } ) ( interface { } , error ) {
if input , err := validateArg ( toBoolean , arguments , 0 , reflect . String ) ; err != nil {
return nil , err
} else {
switch strings . ToLower ( input . String ( ) ) {
case "true" :
return true , nil
case "false" :
return false , nil
default :
return nil , formatError ( genericError , toBoolean , fmt . Sprintf ( "lowercase argument must be 'true' or 'false' (provided: '%s')" , input . String ( ) ) )
}
}
}
2023-03-23 13:11:56 +01:00
func _jpAdd ( arguments [ ] interface { } , operator string ) ( interface { } , error ) {
2023-04-13 13:29:40 +02:00
op1 , op2 , err := parseArithemticOperands ( arguments , operator )
2021-09-23 03:10:45 +05:30
if err != nil {
return nil , err
}
2023-03-23 13:11:56 +01:00
return op1 . Add ( op2 , operator )
}
2021-09-23 03:10:45 +05:30
2023-03-23 13:11:56 +01:00
func jpAdd ( arguments [ ] interface { } ) ( interface { } , error ) {
return _jpAdd ( arguments , add )
2021-09-23 03:10:45 +05:30
}
2023-03-23 14:29:05 +05:30
func jpSum ( arguments [ ] interface { } ) ( interface { } , error ) {
items , ok := arguments [ 0 ] . ( [ ] interface { } )
if ! ok {
return nil , formatError ( typeMismatchError , sum )
}
if len ( items ) == 0 {
return nil , formatError ( genericError , sum , "at least one element in the array is required" )
}
var err error
2023-03-23 13:11:56 +01:00
result := items [ 0 ]
2023-03-23 14:29:05 +05:30
for _ , item := range items [ 1 : ] {
2023-03-23 13:11:56 +01:00
result , err = _jpAdd ( [ ] interface { } { result , item } , sum )
2023-03-23 14:29:05 +05:30
if err != nil {
return nil , err
}
}
2023-03-23 13:11:56 +01:00
return result , nil
2023-03-23 14:29:05 +05:30
}
2021-09-23 03:10:45 +05:30
func jpSubtract ( arguments [ ] interface { } ) ( interface { } , error ) {
2023-04-13 13:29:40 +02:00
op1 , op2 , err := parseArithemticOperands ( arguments , subtract )
2021-09-23 03:10:45 +05:30
if err != nil {
return nil , err
}
2021-12-07 21:14:46 +05:30
return op1 . Subtract ( op2 )
2021-09-23 03:10:45 +05:30
}
func jpMultiply ( arguments [ ] interface { } ) ( interface { } , error ) {
2023-04-13 13:29:40 +02:00
op1 , op2 , err := parseArithemticOperands ( arguments , multiply )
2021-09-23 03:10:45 +05:30
if err != nil {
return nil , err
}
2021-12-07 21:14:46 +05:30
return op1 . Multiply ( op2 )
2021-09-23 03:10:45 +05:30
}
func jpDivide ( arguments [ ] interface { } ) ( interface { } , error ) {
2023-04-13 13:29:40 +02:00
op1 , op2 , err := parseArithemticOperands ( arguments , divide )
2021-09-23 03:10:45 +05:30
if err != nil {
return nil , err
}
2021-12-07 21:14:46 +05:30
return op1 . Divide ( op2 )
2021-09-23 03:10:45 +05:30
}
func jpModulo ( arguments [ ] interface { } ) ( interface { } , error ) {
2023-04-13 13:29:40 +02:00
op1 , op2 , err := parseArithemticOperands ( arguments , modulo )
2021-09-23 03:10:45 +05:30
if err != nil {
return nil , err
}
2021-12-07 21:14:46 +05:30
return op1 . Modulo ( op2 )
2021-09-23 03:10:45 +05:30
}
2023-07-04 01:01:54 +05:30
func jpRound ( arguments [ ] interface { } ) ( interface { } , error ) {
op , err := validateArg ( round , arguments , 0 , reflect . Float64 )
if err != nil {
return nil , err
}
length , err := validateArg ( round , arguments , 1 , reflect . Float64 )
if err != nil {
return nil , err
}
intLength , err := intNumber ( length . Float ( ) )
if err != nil {
return nil , formatError ( nonIntRoundError , round )
}
if intLength < 0 {
return nil , formatError ( argOutOfBoundsError , round )
}
shift := math . Pow ( 10 , float64 ( intLength ) )
rounded := math . Round ( op . Float ( ) * shift ) / shift
return rounded , nil
}
2021-10-14 19:46:06 +01:00
func jpBase64Decode ( arguments [ ] interface { } ) ( interface { } , error ) {
var err error
str , err := validateArg ( "" , arguments , 0 , reflect . String )
if err != nil {
return nil , err
}
decodedStr , err := base64 . StdEncoding . DecodeString ( str . String ( ) )
if err != nil {
return nil , err
}
return string ( decodedStr ) , nil
}
func jpBase64Encode ( arguments [ ] interface { } ) ( interface { } , error ) {
var err error
str , err := validateArg ( "" , arguments , 0 , reflect . String )
if err != nil {
return nil , err
}
return base64 . StdEncoding . EncodeToString ( [ ] byte ( str . String ( ) ) ) , nil
}
2021-12-06 19:10:34 +08:00
func jpPathCanonicalize ( arguments [ ] interface { } ) ( interface { } , error ) {
var err error
str , err := validateArg ( pathCanonicalize , arguments , 0 , reflect . String )
if err != nil {
return nil , err
}
return filepath . Join ( str . String ( ) ) , nil
}
2021-12-17 02:52:52 -05:00
func jpTruncate ( arguments [ ] interface { } ) ( interface { } , error ) {
var err error
2021-12-20 01:50:46 -05:00
var normalizedLength float64
2021-12-17 02:52:52 -05:00
str , err := validateArg ( truncate , arguments , 0 , reflect . String )
if err != nil {
return nil , err
}
length , err := validateArg ( truncate , arguments , 1 , reflect . Float64 )
if err != nil {
return nil , err
}
2021-12-20 01:50:46 -05:00
if length . Float ( ) < 0 {
normalizedLength = float64 ( 0 )
} else {
normalizedLength = length . Float ( )
}
return trunc . Truncator ( str . String ( ) , int ( normalizedLength ) , trunc . CutStrategy { } ) , nil
2021-12-17 02:52:52 -05:00
}
2021-12-21 21:42:35 +05:30
func jpSemverCompare ( arguments [ ] interface { } ) ( interface { } , error ) {
var err error
v , err := validateArg ( semverCompare , arguments , 0 , reflect . String )
if err != nil {
return nil , err
}
r , err := validateArg ( semverCompare , arguments , 1 , reflect . String )
if err != nil {
return nil , err
}
version , _ := semver . Parse ( v . String ( ) )
expectedRange , err := semver . ParseRange ( r . String ( ) )
if err != nil {
return nil , err
}
if expectedRange ( version ) {
return true , nil
}
return false , nil
}
2022-01-10 21:42:02 +00:00
func jpParseJson ( arguments [ ] interface { } ) ( interface { } , error ) {
input , err := validateArg ( parseJson , arguments , 0 , reflect . String )
if err != nil {
return nil , err
}
var output interface { }
err = json . Unmarshal ( [ ] byte ( input . String ( ) ) , & output )
return output , err
}
2022-01-17 13:41:08 +00:00
func jpParseYAML ( arguments [ ] interface { } ) ( interface { } , error ) {
input , err := validateArg ( parseYAML , arguments , 0 , reflect . String )
if err != nil {
return nil , err
}
jsonData , err := yaml . YAMLToJSON ( [ ] byte ( input . String ( ) ) )
if err != nil {
return nil , err
}
var output interface { }
err = json . Unmarshal ( jsonData , & output )
return output , err
}
2023-06-19 15:45:13 +02:00
func jpLookup ( arguments [ ] interface { } ) ( interface { } , error ) {
switch input := arguments [ 0 ] . ( type ) {
case map [ string ] interface { } :
key , ok := arguments [ 1 ] . ( string )
if ! ok {
return nil , formatError ( invalidArgumentTypeError , lookup , 2 , "String" )
}
return input [ key ] , nil
case [ ] interface { } :
key , ok := arguments [ 1 ] . ( float64 )
if ! ok {
return nil , formatError ( invalidArgumentTypeError , lookup , 2 , "Number" )
}
keyInt , err := intNumber ( key )
if err != nil {
return nil , fmt . Errorf (
"JMESPath function '%s': argument #2: %s" ,
lookup , err . Error ( ) ,
)
}
if keyInt < 0 || keyInt > len ( input ) - 1 {
return nil , nil
}
return input [ keyInt ] , nil
default :
return nil , formatError ( invalidArgumentTypeError , lookup , 1 , "Object or Array" )
}
}
2022-05-04 06:33:24 -04:00
func jpItems ( arguments [ ] interface { } ) ( interface { } , error ) {
keyName , ok := arguments [ 1 ] . ( string )
if ! ok {
2023-06-19 15:45:13 +02:00
return nil , formatError ( invalidArgumentTypeError , items , 2 , "String" )
2022-05-04 06:33:24 -04:00
}
valName , ok := arguments [ 2 ] . ( string )
if ! ok {
2023-06-19 15:45:13 +02:00
return nil , formatError ( invalidArgumentTypeError , items , 3 , "String" )
2022-05-04 06:33:24 -04:00
}
2023-02-01 06:43:58 +01:00
switch input := arguments [ 0 ] . ( type ) {
case map [ string ] interface { } :
2023-02-02 14:19:35 +01:00
keys := make ( [ ] string , 0 , len ( input ) )
2023-02-01 06:43:58 +01:00
// Sort the keys so that the output is deterministic
for key := range input {
keys = append ( keys , key )
}
sort . Strings ( keys )
2023-02-02 14:19:35 +01:00
arrayOfObj := make ( [ ] map [ string ] interface { } , 0 , len ( input ) )
2023-02-01 06:43:58 +01:00
for _ , key := range keys {
arrayOfObj = append ( arrayOfObj , map [ string ] interface { } {
keyName : key ,
valName : input [ key ] ,
} )
}
return arrayOfObj , nil
case [ ] interface { } :
2023-02-02 14:19:35 +01:00
arrayOfObj := make ( [ ] map [ string ] interface { } , 0 , len ( input ) )
2023-02-01 06:43:58 +01:00
for index , value := range input {
arrayOfObj = append ( arrayOfObj , map [ string ] interface { } {
keyName : float64 ( index ) ,
valName : value ,
} )
}
return arrayOfObj , nil
default :
2023-06-19 15:45:13 +02:00
return nil , formatError ( invalidArgumentTypeError , items , 1 , "Object or Array" )
2022-05-04 06:33:24 -04:00
}
}
2022-05-07 13:05:04 +01:00
func jpObjectFromLists ( arguments [ ] interface { } ) ( interface { } , error ) {
keys , ok := arguments [ 0 ] . ( [ ] interface { } )
if ! ok {
2023-06-19 15:45:13 +02:00
return nil , formatError ( invalidArgumentTypeError , objectFromLists , 1 , "Array" )
2022-05-07 13:05:04 +01:00
}
values , ok := arguments [ 1 ] . ( [ ] interface { } )
if ! ok {
2023-06-19 15:45:13 +02:00
return nil , formatError ( invalidArgumentTypeError , objectFromLists , 2 , "Array" )
2022-05-07 13:05:04 +01:00
}
output := map [ string ] interface { } { }
for i , ikey := range keys {
key , err := ifaceToString ( ikey )
if err != nil {
2023-06-19 15:45:13 +02:00
return nil , formatError ( invalidArgumentTypeError , objectFromLists , 1 , "StringArray" )
2022-05-07 13:05:04 +01:00
}
if i < len ( values ) {
output [ key ] = values [ i ]
} else {
output [ key ] = nil
}
}
return output , nil
}
2021-04-17 02:17:00 +03:00
// InterfaceToString casts an interface to a string type
func ifaceToString ( iface interface { } ) ( string , error ) {
2021-10-14 01:00:41 +02:00
switch i := iface . ( type ) {
2021-04-17 02:17:00 +03:00
case int :
2021-10-14 01:00:41 +02:00
return strconv . Itoa ( i ) , nil
2021-04-17 02:17:00 +03:00
case float64 :
2021-10-14 01:00:41 +02:00
return strconv . FormatFloat ( i , 'f' , - 1 , 32 ) , nil
2021-04-17 02:17:00 +03:00
case float32 :
2021-10-14 01:00:41 +02:00
return strconv . FormatFloat ( float64 ( i ) , 'f' , - 1 , 32 ) , nil
2021-04-17 02:17:00 +03:00
case string :
2021-10-14 01:00:41 +02:00
return i , nil
2021-04-17 02:17:00 +03:00
case bool :
2021-10-14 01:00:41 +02:00
return strconv . FormatBool ( i ) , nil
2021-04-17 02:17:00 +03:00
default :
return "" , errors . New ( "error, undefined type cast" )
}
}
2022-09-07 21:52:30 +05:30
func jpRandom ( arguments [ ] interface { } ) ( interface { } , error ) {
pattern := arguments [ 0 ] . ( string )
if pattern == "" {
return "" , errors . New ( "no pattern provided" )
}
2023-04-03 17:10:47 +05:30
b := make ( [ ] byte , 8 )
_ , err := rand . Read ( b )
if err != nil {
return nil , err
}
2022-09-07 21:52:30 +05:30
ans , err := regen . Generate ( pattern )
if err != nil {
2022-09-26 15:33:52 +02:00
return nil , err
2022-09-07 21:52:30 +05:30
}
return ans , nil
}
2022-09-28 19:15:39 +01:00
2023-04-14 15:06:38 +05:30
func encode [ T any ] ( in T ) ( interface { } , error ) {
buf := new ( bytes . Buffer )
enc := json . NewEncoder ( buf )
if err := enc . Encode ( in ) ; err != nil {
2022-09-28 19:15:39 +01:00
return nil , err
}
2023-04-14 15:06:38 +05:30
res := map [ string ] interface { } { }
if err := json . Unmarshal ( buf . Bytes ( ) , & res ) ; err != nil {
return nil , err
2022-09-28 19:15:39 +01:00
}
2023-04-14 15:06:38 +05:30
return res , nil
}
2022-09-28 19:15:39 +01:00
2023-04-14 15:06:38 +05:30
func jpX509Decode ( arguments [ ] interface { } ) ( interface { } , error ) {
parseSubjectPublicKeyInfo := func ( data [ ] byte ) ( * rsa . PublicKey , error ) {
spki := cryptobyte . String ( data )
2022-09-28 19:15:39 +01:00
if ! spki . ReadASN1 ( & spki , cryptobyte_asn1 . SEQUENCE ) {
2023-04-14 15:06:38 +05:30
return nil , errors . New ( "writing asn.1 element to 'spki' failed" )
2022-09-28 19:15:39 +01:00
}
var pkAISeq cryptobyte . String
if ! spki . ReadASN1 ( & pkAISeq , cryptobyte_asn1 . SEQUENCE ) {
2023-04-14 15:06:38 +05:30
return nil , errors . New ( "writing asn.1 element to 'pkAISeq' failed" )
2022-09-28 19:15:39 +01:00
}
var spk asn1 . BitString
if ! spki . ReadASN1BitString ( & spk ) {
2023-04-14 15:06:38 +05:30
return nil , errors . New ( "writing asn.1 bit string to 'spk' failed" )
2022-09-28 19:15:39 +01:00
}
2023-04-14 15:06:38 +05:30
if kk , err := x509 . ParsePKCS1PublicKey ( spk . Bytes ) ; err != nil {
return nil , err
} else {
return kk , nil
2022-09-28 19:15:39 +01:00
}
}
2023-04-14 15:06:38 +05:30
if input , err := validateArg ( x509_decode , arguments , 0 , reflect . String ) ; err != nil {
return nil , err
} else if block , _ := pem . Decode ( [ ] byte ( input . String ( ) ) ) ; block == nil {
return nil , errors . New ( "failed to decode PEM block" )
} else {
switch block . Type {
case "CERTIFICATE" :
var cert * x509 . Certificate
if cert , err = x509 . ParseCertificate ( block . Bytes ) ; err != nil {
return nil , err
} else if cert . PublicKeyAlgorithm != x509 . RSA {
return nil , errors . New ( "certificate should use rsa algorithm" )
} else if pk , err := parseSubjectPublicKeyInfo ( cert . RawSubjectPublicKeyInfo ) ; err != nil {
return nil , errors . New ( "failed to parse subject public key info" )
} else {
cert . PublicKey = PublicKey {
N : pk . N . String ( ) ,
E : pk . E ,
}
return encode ( cert )
}
case "CERTIFICATE REQUEST" :
var csr * x509 . CertificateRequest
if csr , err = x509 . ParseCertificateRequest ( block . Bytes ) ; err != nil {
return nil , err
} else if csr . PublicKeyAlgorithm != x509 . RSA {
return nil , errors . New ( "certificate should use rsa algorithm" )
} else if pk , err := parseSubjectPublicKeyInfo ( csr . RawSubjectPublicKeyInfo ) ; err != nil {
return nil , errors . New ( "failed to parse subject public key info" )
} else {
csr . PublicKey = PublicKey {
N : pk . N . String ( ) ,
E : pk . E ,
}
return encode ( csr )
}
default :
return nil , errors . New ( "PEM block neither contains a CERTIFICATE or CERTIFICATE REQUEST" )
}
2022-09-28 19:15:39 +01:00
}
}
2023-04-13 18:13:40 +02:00
func jpImageNormalize ( configuration config . Configuration ) gojmespath . JpFunction {
return func ( arguments [ ] interface { } ) ( interface { } , error ) {
if image , err := validateArg ( imageNormalize , arguments , 0 , reflect . String ) ; err != nil {
return nil , err
} else if infos , err := imageutils . GetImageInfo ( image . String ( ) , configuration ) ; err != nil {
return nil , formatError ( genericError , imageNormalize , err )
} else {
return infos . String ( ) , nil
}
}
}
2023-11-21 12:17:26 +08:00
func jpIsExternalURL ( arguments [ ] interface { } ) ( interface { } , error ) {
var err error
str , err := validateArg ( pathCanonicalize , arguments , 0 , reflect . String )
if err != nil {
return nil , err
}
parsedURL , err := url . Parse ( str . String ( ) )
if err != nil {
return false , err
}
ip := net . ParseIP ( parsedURL . Hostname ( ) )
if ip != nil {
return ! ( ip . IsLoopback ( ) || ip . IsPrivate ( ) ) , nil
}
// If it can't be parsed as an IP, then resolve the domain name
ips , err := net . LookupIP ( parsedURL . Hostname ( ) )
if err != nil {
return nil , err
}
for _ , ip := range ips {
if ip . IsLoopback ( ) || ip . IsPrivate ( ) {
return false , nil
}
}
return true , nil
}
2024-01-05 16:14:26 +05:30
func jpSha256 ( arguments [ ] interface { } ) ( interface { } , error ) {
var err error
str , err := validateArg ( "" , arguments , 0 , reflect . String )
if err != nil {
return nil , err
}
hasher := sha256 . New ( )
_ , err = hasher . Write ( [ ] byte ( str . String ( ) ) )
if err != nil {
return "" , err
}
hashedBytes := hasher . Sum ( nil )
return hex . EncodeToString ( hashedBytes ) , nil
}