From 51e9fec65d17b507655ca454783bc8a278fc48b2 Mon Sep 17 00:00:00 2001 From: Jingfang Liu Date: Tue, 13 Nov 2018 15:56:06 -0800 Subject: [PATCH] allow accessing labels and annotations in vars --- k8sdeps/kunstruct/helper.go | 71 ++++++++++++++++++++++++++++++++++ k8sdeps/kunstruct/kunstruct.go | 7 +++- 2 files changed, 76 insertions(+), 2 deletions(-) create mode 100644 k8sdeps/kunstruct/helper.go diff --git a/k8sdeps/kunstruct/helper.go b/k8sdeps/kunstruct/helper.go new file mode 100644 index 000000000..e0b2f3775 --- /dev/null +++ b/k8sdeps/kunstruct/helper.go @@ -0,0 +1,71 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package kunstruct provides unstructured from api machinery and factory for creating unstructured +package kunstruct + +import ( + "fmt" + "strings" +) + +func parseFields(path string) ([]string, error) { + if !strings.Contains(path, "[") { + return strings.Split(path, "."), nil + } + + var fields []string + start := 0 + insideParentheses := false + for i := range path { + switch path[i] { + case '.': + if !insideParentheses { + fields = append(fields, path[start:i]) + start = i + 1 + } + case '[': + if !insideParentheses { + if i == start { + start = i + 1 + } else { + fields = append(fields, path[start:i]) + start = i + 1 + } + insideParentheses = true + } else { + return nil, fmt.Errorf("nested parentheses are not allowed: %s", path) + } + case ']': + if insideParentheses { + fields = append(fields, path[start:i]) + start = i + 1 + insideParentheses = false + } else { + return nil, fmt.Errorf("Invalid field path %s", path) + } + } + } + if start < len(path)-1 { + fields = append(fields, path[start:]) + } + for i, f := range fields { + if strings.HasPrefix(f, "\"") || strings.HasPrefix(f, "'") { + fields[i] = strings.Trim(f, "\"'") + } + } + return fields, nil +} diff --git a/k8sdeps/kunstruct/kunstruct.go b/k8sdeps/kunstruct/kunstruct.go index 6bc8fad24..5ad306bf5 100644 --- a/k8sdeps/kunstruct/kunstruct.go +++ b/k8sdeps/kunstruct/kunstruct.go @@ -20,7 +20,6 @@ package kunstruct import ( "encoding/json" "fmt" - "strings" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" @@ -80,8 +79,12 @@ func (fs *UnstructAdapter) SetMap(m map[string]interface{}) { // GetFieldValue returns value at the given fieldpath. func (fs *UnstructAdapter) GetFieldValue(path string) (string, error) { + fields, err := parseFields(path) + if err != nil { + return "", err + } s, found, err := unstructured.NestedString( - fs.UnstructuredContent(), strings.Split(path, ".")...) + fs.UnstructuredContent(), fields...) if found || err != nil { return s, err }