1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-05 15:37:19 +00:00
kyverno/pkg/utils/api/json.go
Charles-Edouard Brétéché baacf60156
refactor: move utils into sub packages (#5828)
Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
2023-01-03 09:33:09 +00:00

86 lines
2.7 KiB
Go

package api
import (
"encoding/json"
"fmt"
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
"k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
)
// Deserialize "apiextensions.JSON" to a typed array
func DeserializeJSONArray[T any](in apiextensions.JSON) ([]T, error) {
if in == nil {
return nil, nil
}
data, err := json.Marshal(in)
if err != nil {
return nil, err
}
var res []T
if err := json.Unmarshal(data, &res); err != nil {
return nil, err
}
return res, nil
}
// ApiextensionsJsonToKyvernoConditions takes in user-provided conditions in abstract apiextensions.JSON form
// and converts it into []kyverno.Condition or kyverno.AnyAllConditions according to its content.
// it also helps in validating the condtions as it returns an error when the conditions are provided wrongfully by the user.
func ApiextensionsJsonToKyvernoConditions(in apiextensions.JSON) (interface{}, error) {
path := "preconditions/validate.deny.conditions"
// checks for the existence any other field apart from 'any'/'all' under preconditions/validate.deny.conditions
unknownFieldChecker := func(jsonByteArr []byte, path string) error {
allowedKeys := map[string]bool{
"any": true,
"all": true,
}
var jsonDecoded map[string]interface{}
if err := json.Unmarshal(jsonByteArr, &jsonDecoded); err != nil {
return fmt.Errorf("error occurred while checking for unknown fields under %s: %+v", path, err)
}
for k := range jsonDecoded {
if !allowedKeys[k] {
return fmt.Errorf("unknown field '%s' found under %s", k, path)
}
}
return nil
}
// marshalling the abstract apiextensions.JSON back to JSON form
jsonByte, err := json.Marshal(in)
if err != nil {
return nil, fmt.Errorf("error occurred while marshalling %s: %+v", path, err)
}
var kyvernoOldConditions []kyvernov1.Condition
if err = json.Unmarshal(jsonByte, &kyvernoOldConditions); err == nil {
var validConditionOperator bool
for _, jsonOp := range kyvernoOldConditions {
for _, validOp := range kyvernov1.ConditionOperators {
if jsonOp.Operator == validOp {
validConditionOperator = true
}
}
if !validConditionOperator {
return nil, fmt.Errorf("invalid condition operator: %s", jsonOp.Operator)
}
validConditionOperator = false
}
return kyvernoOldConditions, nil
}
var kyvernoAnyAllConditions kyvernov1.AnyAllConditions
if err = json.Unmarshal(jsonByte, &kyvernoAnyAllConditions); err == nil {
// checking if unknown fields exist or not
err = unknownFieldChecker(jsonByte, path)
if err != nil {
return nil, fmt.Errorf("error occurred while parsing %s: %+v", path, err)
}
return kyvernoAnyAllConditions, nil
}
return nil, fmt.Errorf("error occurred while parsing %s: %+v", path, err)
}