Skip to content

Commit

Permalink
Support jsonpath in OperandConfig value reference (#994)
Browse files Browse the repository at this point in the history
Signed-off-by: Daniel Fan <[email protected]>
  • Loading branch information
Daniel-Fan authored Nov 7, 2023
1 parent b94e873 commit ff4546c
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 25 deletions.
23 changes: 3 additions & 20 deletions controllers/operandbindinfo/operandbindinfo_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
package operandbindinfo

import (
"bytes"
"context"
"fmt"
"reflect"
Expand All @@ -37,7 +36,6 @@ import (
utilerrors "k8s.io/apimachinery/pkg/util/errors"
"k8s.io/client-go/discovery"
"k8s.io/client-go/rest"
"k8s.io/client-go/util/jsonpath"
"k8s.io/klog"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/builder"
Expand Down Expand Up @@ -677,25 +675,10 @@ func sanitizeOdlmRouteData(m map[string]string, route ocproute.RouteSpec) (map[s
// stringified
func sanitizeServiceData(m map[string]string, service corev1.Service) (map[string]string, error) {
sanitized := make(map[string]string, len(m))
jpath := jsonpath.New("sanitizeServiceData")
for k, v := range m {
trueValue := ""
stringParts := strings.Split(v, "+")
for _, s := range stringParts {
actual := s
if strings.HasPrefix(s, ".") {
if len(s) > 1 {
if err := jpath.Parse("{" + s + "}"); err != nil {
return nil, err
}
buf := new(bytes.Buffer)
if err := jpath.Execute(buf, service); err != nil {
return nil, err
}
actual = buf.String()
}
}
trueValue += actual
trueValue, err := util.SanitizeObjectString(v, service)
if err != nil {
return nil, err
}
sanitized[k] = trueValue
}
Expand Down
8 changes: 3 additions & 5 deletions controllers/operator/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -672,13 +672,11 @@ func (m *ODLMOperator) GetValueRefFromObject(ctx context.Context, instanceType,
return "", nil
}

value, ok, err := unstructured.NestedString(obj.Object, strings.Split(path, ".")...)
sanitizedString, err := util.SanitizeObjectString(path, obj.Object)
if err != nil {
return "", errors.Wrapf(err, "failed to parse path %v from %s %s/%s", path, obj.GetKind(), obj.GetNamespace(), obj.GetName())
} else if !ok {
return "", errors.Errorf("failed to get path %v from %s %s/%s, the value is not found", path, obj.GetKind(), obj.GetNamespace(), obj.GetName())
}

klog.V(2).Infof("Get value %s from %s %s/%s", value, objKind, obj.GetNamespace(), obj.GetName())
return value, nil
klog.V(2).Infof("Get value %s from %s %s/%s", sanitizedString, objKind, obj.GetNamespace(), obj.GetName())
return sanitizedString, nil
}
32 changes: 32 additions & 0 deletions controllers/util/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package util

import (
"bytes"
"fmt"
"os"
"sort"
Expand All @@ -31,6 +32,7 @@ import (
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/discovery"
"k8s.io/client-go/util/jsonpath"
)

type TemplateValueRef struct {
Expand Down Expand Up @@ -286,3 +288,33 @@ func CompareSecret(secret *corev1.Secret, existingSecret *corev1.Secret) (needUp
func CompareConfigMap(configMap *corev1.ConfigMap, existingConfigMap *corev1.ConfigMap) (needUpdate bool) {
return !equality.Semantic.DeepEqual(configMap.GetLabels(), existingConfigMap.GetLabels()) || !equality.Semantic.DeepEqual(configMap.Data, existingConfigMap.Data) || !equality.Semantic.DeepEqual(configMap.BinaryData, existingConfigMap.BinaryData)
}

// SanitizeObjectString takes a string, i.e. .metadata.namespace, and a K8s object
// and returns a string got from K8s object. The required string
// is sanitized because the values are YAML fields in a K8s object.
// Ensures that:
// 1. the field actually exists, otherwise returns an error
// 2. extracts the value from the K8s Service's field, the value will be
// stringified
func SanitizeObjectString(jsonPath string, data interface{}) (string, error) {
jpath := jsonpath.New("sanitizeObjectData")
stringParts := strings.Split(jsonPath, "+")
sanitized := ""
for _, s := range stringParts {
actual := s
if strings.HasPrefix(s, ".") {
if len(s) > 1 {
if err := jpath.Parse("{" + s + "}"); err != nil {
return "", err
}
buf := new(bytes.Buffer)
if err := jpath.Execute(buf, data); err != nil {
return "", err
}
actual = buf.String()
}
}
sanitized += actual
}
return sanitized, nil
}

0 comments on commit ff4546c

Please sign in to comment.