mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-09-15 12:18:57 +00:00
add comments in refvar transformer
Refactor change
This commit is contained in:
@@ -79,7 +79,7 @@ func (a *applicationImpl) Resources() (resmap.ResMap, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
t, err := a.getHashAndReferenceTransformer(res)
|
t, err := a.newHashAndReferenceTransformer(res)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -125,7 +125,7 @@ func (a *applicationImpl) SemiResources() (resmap.ResMap, error) {
|
|||||||
return nil, errs
|
return nil, errs
|
||||||
}
|
}
|
||||||
|
|
||||||
t, err := a.getTransformer(patches)
|
t, err := a.newTransformer(patches)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -144,7 +144,7 @@ func (a *applicationImpl) RawResources() (resmap.ResMap, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
t, err := a.getHashAndReferenceTransformer(res)
|
t, err := a.newHashAndReferenceTransformer(res)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -220,12 +220,12 @@ func (a *applicationImpl) subApp() ([]Application, error) {
|
|||||||
return apps, nil
|
return apps, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// getTransformer generates the following transformers:
|
// newTransformer generates the following transformers:
|
||||||
// 1) apply overlay
|
// 1) apply overlay
|
||||||
// 2) name prefix
|
// 2) name prefix
|
||||||
// 3) apply labels
|
// 3) apply labels
|
||||||
// 4) apply annotations
|
// 4) apply annotations
|
||||||
func (a *applicationImpl) getTransformer(patches []*resource.Resource) (transformers.Transformer, error) {
|
func (a *applicationImpl) newTransformer(patches []*resource.Resource) (transformers.Transformer, error) {
|
||||||
ts := []transformers.Transformer{}
|
ts := []transformers.Transformer{}
|
||||||
|
|
||||||
ot, err := transformers.NewOverlayTransformer(patches)
|
ot, err := transformers.NewOverlayTransformer(patches)
|
||||||
@@ -257,11 +257,11 @@ func (a *applicationImpl) getTransformer(patches []*resource.Resource) (transfor
|
|||||||
return transformers.NewMultiTransformer(ts), nil
|
return transformers.NewMultiTransformer(ts), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// getHashAndReferenceTransformer generates the following transformers:
|
// newHashAndReferenceTransformer generates the following transformers:
|
||||||
// 1) name hash for configmap and secrests
|
// 1) name hash for configmap and secrests
|
||||||
// 2) apply name reference
|
// 2) apply name reference
|
||||||
// 3) apply reference variables
|
// 3) apply reference variables
|
||||||
func (a *applicationImpl) getHashAndReferenceTransformer(allRes resmap.ResMap) (transformers.Transformer, error) {
|
func (a *applicationImpl) newHashAndReferenceTransformer(allRes resmap.ResMap) (transformers.Transformer, error) {
|
||||||
ts := []transformers.Transformer{}
|
ts := []transformers.Transformer{}
|
||||||
nht := transformers.NewNameHashTransformer()
|
nht := transformers.NewNameHashTransformer()
|
||||||
ts = append(ts, nht)
|
ts = append(ts, nht)
|
||||||
@@ -271,7 +271,7 @@ func (a *applicationImpl) getHashAndReferenceTransformer(allRes resmap.ResMap) (
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
ts = append(ts, nrt)
|
ts = append(ts, nrt)
|
||||||
t, err := a.getVariableReferenceTransformer(allRes)
|
t, err := a.newVariableReferenceTransformer(allRes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -280,7 +280,7 @@ func (a *applicationImpl) getHashAndReferenceTransformer(allRes resmap.ResMap) (
|
|||||||
return transformers.NewMultiTransformer(ts), nil
|
return transformers.NewMultiTransformer(ts), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *applicationImpl) getVariableReferenceTransformer(allRes resmap.ResMap) (transformers.Transformer, error) {
|
func (a *applicationImpl) newVariableReferenceTransformer(allRes resmap.ResMap) (transformers.Transformer, error) {
|
||||||
refvars, err := a.resolveRefVars(allRes)
|
refvars, err := a.resolveRefVars(allRes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -314,9 +314,9 @@ func (a *applicationImpl) resolveRefVars(resources resmap.ResMap) (map[string]st
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, refvar := range vars {
|
for _, refvar := range vars {
|
||||||
refGVKN := gvkn(refvar)
|
refGVKN := resource.NewResId(refvar.ObjRef.GroupVersionKind(), refvar.ObjRef.Name)
|
||||||
if r, found := resources[refGVKN]; found {
|
if r, found := resources[refGVKN]; found {
|
||||||
s, err := getFieldAsString(r.Unstruct().UnstructuredContent(), strings.Split(refvar.FieldRef.FieldPath, "."))
|
s, err := resource.GetFieldValue(r.Unstruct().UnstructuredContent(), strings.Split(refvar.FieldRef.FieldPath, "."))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to resolve referred var: %+v", refvar)
|
return nil, fmt.Errorf("failed to resolve referred var: %+v", refvar)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,54 +0,0 @@
|
|||||||
/*
|
|
||||||
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 app
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/kubernetes-sigs/kustomize/pkg/resource"
|
|
||||||
"github.com/kubernetes-sigs/kustomize/pkg/types"
|
|
||||||
)
|
|
||||||
|
|
||||||
func gvkn(rv types.Var) resource.ResId {
|
|
||||||
return resource.NewResId(rv.ObjRef.GroupVersionKind(), rv.ObjRef.Name)
|
|
||||||
}
|
|
||||||
|
|
||||||
func getFieldAsString(m map[string]interface{}, pathToField []string) (string, error) {
|
|
||||||
if len(pathToField) == 0 {
|
|
||||||
return "", fmt.Errorf("Field not found")
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(pathToField) == 1 {
|
|
||||||
if v, found := m[pathToField[0]]; found {
|
|
||||||
if s, ok := v.(string); ok {
|
|
||||||
return s, nil
|
|
||||||
}
|
|
||||||
return "", fmt.Errorf("value at fieldpath is not of string type")
|
|
||||||
}
|
|
||||||
return "", fmt.Errorf("field at given fieldpath does not exist")
|
|
||||||
}
|
|
||||||
|
|
||||||
curr, rest := pathToField[0], pathToField[1]
|
|
||||||
|
|
||||||
v := m[curr]
|
|
||||||
switch typedV := v.(type) {
|
|
||||||
case map[string]interface{}:
|
|
||||||
return getFieldAsString(typedV, []string{rest})
|
|
||||||
default:
|
|
||||||
return "", fmt.Errorf("%#v is not expected to be a primitive type", typedV)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -18,6 +18,7 @@ package resource
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
@@ -108,3 +109,29 @@ func newUnstructuredFromObject(in runtime.Object) (*unstructured.Unstructured, e
|
|||||||
err = out.UnmarshalJSON(marshaled)
|
err = out.UnmarshalJSON(marshaled)
|
||||||
return &out, err
|
return &out, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetFieldValue(m map[string]interface{}, pathToField []string) (string, error) {
|
||||||
|
if len(pathToField) == 0 {
|
||||||
|
return "", fmt.Errorf("Field not found")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(pathToField) == 1 {
|
||||||
|
if v, found := m[pathToField[0]]; found {
|
||||||
|
if s, ok := v.(string); ok {
|
||||||
|
return s, nil
|
||||||
|
}
|
||||||
|
return "", fmt.Errorf("value at fieldpath is not of string type")
|
||||||
|
}
|
||||||
|
return "", fmt.Errorf("field at given fieldpath does not exist")
|
||||||
|
}
|
||||||
|
|
||||||
|
curr, rest := pathToField[0], pathToField[1]
|
||||||
|
|
||||||
|
v := m[curr]
|
||||||
|
switch typedV := v.(type) {
|
||||||
|
case map[string]interface{}:
|
||||||
|
return GetFieldValue(typedV, []string{rest})
|
||||||
|
default:
|
||||||
|
return "", fmt.Errorf("%#v is not expected to be a primitive type", typedV)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -14,10 +14,9 @@ See the License for the specific language governing permissions and
|
|||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package app
|
package resource
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -31,21 +30,37 @@ func TestGetFieldAsString(t *testing.T) {
|
|||||||
"name": "service-name",
|
"name": "service-name",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
p := []string{"Kind"}
|
|
||||||
s, _ := getFieldAsString(m, p)
|
tests := []struct {
|
||||||
if s != "Service" {
|
pathToField []string
|
||||||
t.Errorf("Expected to get Service, but actually got %s", s)
|
expectedName string
|
||||||
|
expectedError bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
pathToField: []string{"Kind"},
|
||||||
|
expectedName: "Service",
|
||||||
|
expectedError: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pathToField: []string{"metadata", "name"},
|
||||||
|
expectedName: "service-name",
|
||||||
|
expectedError: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pathToField: []string{"metadata", "non-existing-field"},
|
||||||
|
expectedName: "",
|
||||||
|
expectedError: true,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
p = []string{"metadata", "name"}
|
for _, test := range tests {
|
||||||
s, _ = getFieldAsString(m, p)
|
s, err := GetFieldValue(m, test.pathToField)
|
||||||
if s != "service-name" {
|
if test.expectedError && err == nil {
|
||||||
t.Errorf("Expected to get service-name, but actually got %s", s)
|
t.Fatalf("should return error, but no error returned")
|
||||||
}
|
} else {
|
||||||
|
if test.expectedName != s {
|
||||||
p = []string{"metadata", "non-existing-field"}
|
t.Fatalf("Got:%s expected:%s", s, test.expectedName)
|
||||||
s, err := getFieldAsString(m, p)
|
}
|
||||||
if !strings.HasSuffix(err.Error(), "field at given fieldpath does not exist") {
|
}
|
||||||
t.Errorf("Unexpected failure due to incorrect error message %s", err.Error())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -13,6 +13,7 @@ type refvarTransformer struct {
|
|||||||
vars map[string]string
|
vars map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewRefVarTransformer returns a Trasformer that replaces $(VAR) style variables with values.
|
||||||
func NewRefVarTransformer(vars map[string]string) (Transformer, error) {
|
func NewRefVarTransformer(vars map[string]string) (Transformer, error) {
|
||||||
return &refvarTransformer{
|
return &refvarTransformer{
|
||||||
vars: vars,
|
vars: vars,
|
||||||
@@ -33,17 +34,16 @@ func NewRefVarTransformer(vars map[string]string) (Transformer, error) {
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Transform determines the final values of variables:
|
||||||
|
//
|
||||||
|
// 1. Determine the final value of each variable:
|
||||||
|
// a. If the variable's Value is set, expand the `$(var)` references to other
|
||||||
|
// variables in the .Value field; the sources of variables are the declared
|
||||||
|
// variables of the container and the service environment variables
|
||||||
|
// b. If a source is defined for an environment variable, resolve the source
|
||||||
|
// 2. Create the container's environment in the order variables are declared
|
||||||
|
// 3. Add remaining service environment vars
|
||||||
func (rv *refvarTransformer) Transform(resources resmap.ResMap) error {
|
func (rv *refvarTransformer) Transform(resources resmap.ResMap) error {
|
||||||
// Determine the final values of variables:
|
|
||||||
//
|
|
||||||
// 1. Determine the final value of each variable:
|
|
||||||
// a. If the variable's Value is set, expand the `$(var)` references to other
|
|
||||||
// variables in the .Value field; the sources of variables are the declared
|
|
||||||
// variables of the container and the service environment variables
|
|
||||||
// b. If a source is defined for an environment variable, resolve the source
|
|
||||||
// 2. Create the container's environment in the order variables are declared
|
|
||||||
// 3. Add remaining service environment vars
|
|
||||||
|
|
||||||
for GVKn := range resources {
|
for GVKn := range resources {
|
||||||
obj := resources[GVKn].Unstruct()
|
obj := resources[GVKn].Unstruct()
|
||||||
objMap := obj.UnstructuredContent()
|
objMap := obj.UnstructuredContent()
|
||||||
|
|||||||
@@ -1,27 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2017 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 (
|
|
||||||
corev1 "k8s.io/api/core/v1"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (v *Var) Defaulting() {
|
|
||||||
if (corev1.ObjectFieldSelector{}) == v.FieldRef {
|
|
||||||
v.FieldRef = corev1.ObjectFieldSelector{FieldPath: "metadata.name"}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -16,10 +16,6 @@ limitations under the License.
|
|||||||
|
|
||||||
package types
|
package types
|
||||||
|
|
||||||
import (
|
|
||||||
corev1 "k8s.io/api/core/v1"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Kustomization holds the information needed to generate customized k8s api resources.
|
// Kustomization holds the information needed to generate customized k8s api resources.
|
||||||
type Kustomization struct {
|
type Kustomization struct {
|
||||||
// NamePrefix will prefix the names of all resources mentioned in the kustomization
|
// NamePrefix will prefix the names of all resources mentioned in the kustomization
|
||||||
@@ -136,23 +132,3 @@ type DataSources struct {
|
|||||||
// i.e. a Docker .env file or a .ini file.
|
// i.e. a Docker .env file or a .ini file.
|
||||||
EnvSource string `json:"env,omitempty" yaml:"env,omitempty"`
|
EnvSource string `json:"env,omitempty" yaml:"env,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Var represents a variable whose value will be sourced
|
|
||||||
// from a field in a Kubernetes object.
|
|
||||||
type Var struct {
|
|
||||||
// Value of identifier name e.g. FOO used in container args, annotations
|
|
||||||
// Appears in pod template as $(FOO)
|
|
||||||
Name string `json:"name" yaml:"name"`
|
|
||||||
|
|
||||||
// ObjRef must refer to a Kubernetes resource under the
|
|
||||||
// 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"`
|
|
||||||
|
|
||||||
// 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"`
|
|
||||||
}
|
|
||||||
|
|||||||
47
pkg/types/var.go
Normal file
47
pkg/types/var.go
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2017 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 (
|
||||||
|
corev1 "k8s.io/api/core/v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Var represents a variable whose value will be sourced
|
||||||
|
// from a field in a Kubernetes object.
|
||||||
|
type Var struct {
|
||||||
|
// Value of identifier name e.g. FOO used in container args, annotations
|
||||||
|
// Appears in pod template as $(FOO)
|
||||||
|
Name string `json:"name" yaml:"name"`
|
||||||
|
|
||||||
|
// ObjRef must refer to a Kubernetes resource under the
|
||||||
|
// 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"`
|
||||||
|
|
||||||
|
// 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"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *Var) Defaulting() {
|
||||||
|
if (corev1.ObjectFieldSelector{}) == v.FieldRef {
|
||||||
|
v.FieldRef = corev1.ObjectFieldSelector{FieldPath: "metadata.name"}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user