diff --git a/pkg/expansion/expand_test.go b/pkg/expansion/expand_test.go index ecdff304c..e418e33a1 100644 --- a/pkg/expansion/expand_test.go +++ b/pkg/expansion/expand_test.go @@ -18,12 +18,14 @@ package expansion import ( "testing" - - api "k8s.io/api/core/v1" ) func TestMapReference(t *testing.T) { - envs := []api.EnvVar{ + type env struct { + Name string + Value string + } + envs := []env{ { Name: "FOO", Value: "bar", diff --git a/pkg/target/kusttarget.go b/pkg/target/kusttarget.go index e2b331959..ae95e2df8 100644 --- a/pkg/target/kusttarget.go +++ b/pkg/target/kusttarget.go @@ -29,7 +29,6 @@ import ( "sigs.k8s.io/kustomize/pkg/constants" "sigs.k8s.io/kustomize/pkg/crds" "sigs.k8s.io/kustomize/pkg/fs" - "sigs.k8s.io/kustomize/pkg/gvk" interror "sigs.k8s.io/kustomize/pkg/internal/error" "sigs.k8s.io/kustomize/pkg/loader" "sigs.k8s.io/kustomize/pkg/patch" @@ -296,8 +295,7 @@ func (kt *KustTarget) resolveRefVars(m resmap.ResMap) (map[string]string, error) return result, err } for _, v := range vars { - id := resource.NewResId( - gvk.FromSchemaGvk(v.ObjRef.GroupVersionKind()), v.ObjRef.Name) + id := resource.NewResId(v.ObjRef.GVK(), v.ObjRef.Name) if r, found := m.DemandOneMatchForId(id); found { s, err := r.GetFieldValue(v.FieldRef.FieldPath) if err != nil { diff --git a/pkg/types/var.go b/pkg/types/var.go index d3b2e73e5..4d48c9619 100644 --- a/pkg/types/var.go +++ b/pkg/types/var.go @@ -17,7 +17,8 @@ limitations under the License. package types import ( - corev1 "k8s.io/api/core/v1" + "sigs.k8s.io/kustomize/pkg/gvk" + "strings" ) // Var represents a variable whose value will be sourced @@ -31,18 +32,51 @@ type Var struct { // purview of this kustomization. ObjRef should use the // raw name of the object (the name specified in its YAML, // before addition of a namePrefix). - ObjRef corev1.ObjectReference `json:"objref" yaml:"objref"` + ObjRef Target `json:"objref" yaml:"objref"` // FieldRef refers to the field of the object referred to by // ObjRef whose value will be extracted for use in // replacing $(FOO). - // If unspecified, this defaults to fieldpath: metadata.name - FieldRef corev1.ObjectFieldSelector `json:"fieldref,omitempty" yaml:"objref,omitempty"` + // If unspecified, this defaults to fieldPath: metadata.name + FieldRef FieldSelector `json:"fieldref,omitempty" yaml:"fieldref,omitempty"` +} + +// Target refers to a kubernetes object by Group, Version, Kind and Name +// gvk.Gvk contains Group, Version and Kind +// APIVersion is added to keep the backward compatibility of using ObjectReference +// for Var.ObjRef +type Target struct { + APIVersion string `json:"apiVersion,omitempty" yaml:"apiVersion,omitempty"` + gvk.Gvk `json:",inline,omitempty" yaml:",inline,omitempty"` + Name string `json:"name" yaml:"name"` +} + +// FieldSelector contains the fieldPath to an object field, such as metadata.name +// This struct is added to keep the backward compatibility of using ObjectFieldSelector +// for Var.FieldRef +type FieldSelector struct { + FieldPath string `json:"fieldPath,omitempty" yaml:"fieldPath,omitempty"` } // Defaulting sets reference to field used by default. func (v *Var) Defaulting() { - if (corev1.ObjectFieldSelector{}) == v.FieldRef { - v.FieldRef = corev1.ObjectFieldSelector{FieldPath: "metadata.name"} + if v.FieldRef.FieldPath == "" { + v.FieldRef.FieldPath = "metadata.name" } } + +// GVK returns the Gvk object in Target +func (t *Target) GVK() gvk.Gvk { + if t.APIVersion == "" { + return t.Gvk + } + versions := strings.Split(t.APIVersion, "/") + if len(versions) == 2 { + t.Group = versions[0] + t.Version = versions[1] + } + if len(versions) == 1 { + t.Version = versions[0] + } + return t.Gvk +} diff --git a/pkg/types/var_test.go b/pkg/types/var_test.go new file mode 100644 index 000000000..ee2b7205a --- /dev/null +++ b/pkg/types/var_test.go @@ -0,0 +1,86 @@ +/* +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 types + +import ( + "gopkg.in/yaml.v2" + "reflect" + "sigs.k8s.io/kustomize/pkg/gvk" + "testing" +) + +func TestGVK(t *testing.T) { + type testcase struct { + data string + expected gvk.Gvk + } + + testcases := []testcase{ + { + data: ` +apiVersion: v1 +kind: Secret +name: my-secret +`, + expected: gvk.Gvk{Group: "", Version: "v1", Kind: "Secret"}, + }, + { + data: ` +apiVersion: myapps/v1 +kind: MyKind +name: my-kind +`, + expected: gvk.Gvk{Group: "myapps", Version: "v1", Kind: "MyKind"}, + }, + { + data: ` +version: v2 +kind: MyKind +name: my-kind +`, + expected: gvk.Gvk{Version: "v2", Kind: "MyKind"}, + }, + } + + for _, tc := range testcases { + var targ Target + err := yaml.Unmarshal([]byte(tc.data), &targ) + if err != nil { + t.Fatalf("Unexpected error %v", err) + } + if !reflect.DeepEqual(targ.GVK(), tc.expected) { + t.Fatalf("Expected %v, but got %v", tc.expected, targ.GVK()) + } + } +} + +func TestDefaulting(t *testing.T) { + v := &Var{ + Name: "SOME_VARIABLE_NAME", + ObjRef: Target{ + Gvk: gvk.Gvk{ + Version: "v1", + Kind: "Secret", + }, + Name: "my-secret", + }, + } + v.Defaulting() + if v.FieldRef.FieldPath != "metadata.name" { + t.Fatalf("var defaulting doesn't behave correctly.\n expected metadata.name, but got %v", v.FieldRef.FieldPath) + } +}