diff --git a/controllers/operandbindinfo/operandbindinfo_controller.go b/controllers/operandbindinfo/operandbindinfo_controller.go index 66067532..2c1bab9c 100644 --- a/controllers/operandbindinfo/operandbindinfo_controller.go +++ b/controllers/operandbindinfo/operandbindinfo_controller.go @@ -17,7 +17,6 @@ package operandbindinfo import ( - "bytes" "context" "fmt" "reflect" @@ -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" @@ -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 } diff --git a/controllers/operator/manager.go b/controllers/operator/manager.go index 3dbb3115..4848d98c 100644 --- a/controllers/operator/manager.go +++ b/controllers/operator/manager.go @@ -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 } diff --git a/controllers/util/util.go b/controllers/util/util.go index a17bf799..5846d374 100644 --- a/controllers/util/util.go +++ b/controllers/util/util.go @@ -17,6 +17,7 @@ package util import ( + "bytes" "fmt" "os" "sort" @@ -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 { @@ -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 +}