mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-05-17 18:25:26 +00:00
Merge pull request #66 from monopole/reduceIndirection
Reduce indirection in code w/r to the unstruct types.
This commit is contained in:
@@ -318,7 +318,8 @@ func (a *applicationImpl) resolveRefVars(resources resmap.ResMap) (map[string]st
|
|||||||
for _, refvar := range vars {
|
for _, refvar := range vars {
|
||||||
refGVKN := resource.NewResId(refvar.ObjRef.GroupVersionKind(), refvar.ObjRef.Name)
|
refGVKN := resource.NewResId(refvar.ObjRef.GroupVersionKind(), refvar.ObjRef.Name)
|
||||||
if r, found := resources[refGVKN]; found {
|
if r, found := resources[refGVKN]; found {
|
||||||
s, err := resource.GetFieldValue(r.Unstruct().UnstructuredContent(), strings.Split(refvar.FieldRef.FieldPath, "."))
|
s, err := resource.GetFieldValue(
|
||||||
|
r.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)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,12 +51,12 @@ func writeYamlToNewDir(in resmap.ResMap, prefix string) (*directory, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
for gvkn, obj := range in {
|
for id, obj := range in {
|
||||||
f, err := dir.newFile(gvkn.String())
|
f, err := dir.newFile(id.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
err = print(obj.Unstruct(), f)
|
err = print(obj, f)
|
||||||
f.Close()
|
f.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -28,42 +28,37 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/util/validation"
|
"k8s.io/apimachinery/pkg/util/validation"
|
||||||
)
|
)
|
||||||
|
|
||||||
func newResourceFromConfigMap(l loader.Loader, cm types.ConfigMapArgs) (*resource.Resource, error) {
|
func newResourceFromConfigMap(l loader.Loader, cmArgs types.ConfigMapArgs) (*resource.Resource, error) {
|
||||||
corev1CM, err := makeConfigMap(l, cm)
|
cm, err := makeConfigMap(l, cmArgs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
return resource.NewResourceWithBehavior(cm, resource.NewGenerationBehavior(cmArgs.Behavior))
|
||||||
data, err := newUnstructuredFromObject(corev1CM)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return resource.NewResource(data, cm.Behavior), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeConfigMap(l loader.Loader, cm types.ConfigMapArgs) (*corev1.ConfigMap, error) {
|
func makeConfigMap(l loader.Loader, cmArgs types.ConfigMapArgs) (*corev1.ConfigMap, error) {
|
||||||
var envPairs, literalPairs, filePairs []kvPair
|
var envPairs, literalPairs, filePairs []kvPair
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
corev1cm := &corev1.ConfigMap{}
|
cm := &corev1.ConfigMap{}
|
||||||
corev1cm.APIVersion = "v1"
|
cm.APIVersion = "v1"
|
||||||
corev1cm.Kind = "ConfigMap"
|
cm.Kind = "ConfigMap"
|
||||||
corev1cm.Name = cm.Name
|
cm.Name = cmArgs.Name
|
||||||
corev1cm.Data = map[string]string{}
|
cm.Data = map[string]string{}
|
||||||
|
|
||||||
if cm.EnvSource != "" {
|
if cmArgs.EnvSource != "" {
|
||||||
envPairs, err = keyValuesFromEnvFile(l, cm.EnvSource)
|
envPairs, err = keyValuesFromEnvFile(l, cmArgs.EnvSource)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("error reading keys from env source file: %s %v", cm.EnvSource, err)
|
return nil, fmt.Errorf("error reading keys from env source file: %s %v", cmArgs.EnvSource, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
literalPairs, err = keyValuesFromLiteralSources(cm.LiteralSources)
|
literalPairs, err = keyValuesFromLiteralSources(cmArgs.LiteralSources)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("error reading key values from literal sources: %v", err)
|
return nil, fmt.Errorf("error reading key values from literal sources: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
filePairs, err = keyValuesFromFileSources(l, cm.FileSources)
|
filePairs, err = keyValuesFromFileSources(l, cmArgs.FileSources)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("error reading key values from file sources: %v", err)
|
return nil, fmt.Errorf("error reading key values from file sources: %v", err)
|
||||||
}
|
}
|
||||||
@@ -72,13 +67,13 @@ func makeConfigMap(l loader.Loader, cm types.ConfigMapArgs) (*corev1.ConfigMap,
|
|||||||
|
|
||||||
// merge key value pairs from all the sources
|
// merge key value pairs from all the sources
|
||||||
for _, kv := range allPairs {
|
for _, kv := range allPairs {
|
||||||
err = addKV(corev1cm.Data, kv)
|
err = addKV(cm.Data, kv)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("error adding key in configmap: %v", err)
|
return nil, fmt.Errorf("error adding key in configmap: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return corev1cm, nil
|
return cm, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func keyValuesFromEnvFile(l loader.Loader, path string) ([]kvPair, error) {
|
func keyValuesFromEnvFile(l loader.Loader, path string) ([]kvPair, error) {
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ package resmap
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"reflect"
|
"reflect"
|
||||||
@@ -30,7 +29,6 @@ import (
|
|||||||
"github.com/kubernetes-sigs/kustomize/pkg/loader"
|
"github.com/kubernetes-sigs/kustomize/pkg/loader"
|
||||||
"github.com/kubernetes-sigs/kustomize/pkg/resource"
|
"github.com/kubernetes-sigs/kustomize/pkg/resource"
|
||||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
|
||||||
k8syaml "k8s.io/apimachinery/pkg/util/yaml"
|
k8syaml "k8s.io/apimachinery/pkg/util/yaml"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -40,8 +38,8 @@ type ResMap map[resource.ResId]*resource.Resource
|
|||||||
// EncodeAsYaml encodes a ResMap to YAML; encoded objects separated by `---`.
|
// EncodeAsYaml encodes a ResMap to YAML; encoded objects separated by `---`.
|
||||||
func (m ResMap) EncodeAsYaml() ([]byte, error) {
|
func (m ResMap) EncodeAsYaml() ([]byte, error) {
|
||||||
ids := []resource.ResId{}
|
ids := []resource.ResId{}
|
||||||
for gvkn := range m {
|
for id := range m {
|
||||||
ids = append(ids, gvkn)
|
ids = append(ids, id)
|
||||||
}
|
}
|
||||||
sort.Sort(IdSlice(ids))
|
sort.Sort(IdSlice(ids))
|
||||||
|
|
||||||
@@ -49,7 +47,7 @@ func (m ResMap) EncodeAsYaml() ([]byte, error) {
|
|||||||
var b []byte
|
var b []byte
|
||||||
buf := bytes.NewBuffer(b)
|
buf := bytes.NewBuffer(b)
|
||||||
for _, id := range ids {
|
for _, id := range ids {
|
||||||
obj := m[id].Unstruct()
|
obj := m[id]
|
||||||
out, err := yaml.Marshal(obj)
|
out, err := yaml.Marshal(obj)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -87,8 +85,8 @@ func (m1 ResMap) ErrorIfNotEqual(m2 ResMap) error {
|
|||||||
if !found {
|
if !found {
|
||||||
return fmt.Errorf("%#v doesn't exist in %#v", id, m2)
|
return fmt.Errorf("%#v doesn't exist in %#v", id, m2)
|
||||||
}
|
}
|
||||||
if !reflect.DeepEqual(obj1.Unstruct(), obj2.Unstruct()) {
|
if !reflect.DeepEqual(obj1, obj2) {
|
||||||
return fmt.Errorf("%#v doesn't match %#v", obj1.Unstruct(), obj2.Unstruct())
|
return fmt.Errorf("%#v doesn't match %#v", obj1, obj2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -153,11 +151,11 @@ func newResMapFromBytes(b []byte) (ResMap, error) {
|
|||||||
|
|
||||||
result := ResMap{}
|
result := ResMap{}
|
||||||
for _, res := range resources {
|
for _, res := range resources {
|
||||||
gvkn := res.Id()
|
id := res.Id()
|
||||||
if _, found := result[gvkn]; found {
|
if _, found := result[id]; found {
|
||||||
return result, fmt.Errorf("GroupVersionKindName: %#v already exists b the map", gvkn)
|
return result, fmt.Errorf("GroupVersionKindName: %#v already exists b the map", id)
|
||||||
}
|
}
|
||||||
result[gvkn] = res
|
result[id] = res
|
||||||
}
|
}
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
@@ -165,11 +163,11 @@ func newResMapFromBytes(b []byte) (ResMap, error) {
|
|||||||
func newResMapFromResourceSlice(resources []*resource.Resource) (ResMap, error) {
|
func newResMapFromResourceSlice(resources []*resource.Resource) (ResMap, error) {
|
||||||
result := ResMap{}
|
result := ResMap{}
|
||||||
for _, res := range resources {
|
for _, res := range resources {
|
||||||
gvkn := res.Id()
|
id := res.Id()
|
||||||
if _, found := result[gvkn]; found {
|
if _, found := result[id]; found {
|
||||||
return nil, fmt.Errorf("duplicated %#v is not allowed", gvkn)
|
return nil, fmt.Errorf("duplicated %#v is not allowed", id)
|
||||||
}
|
}
|
||||||
result[gvkn] = res
|
result[id] = res
|
||||||
}
|
}
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
@@ -197,21 +195,17 @@ func newResourceSliceFromBytes(in []byte) ([]*resource.Resource, error) {
|
|||||||
func Merge(maps ...ResMap) (ResMap, error) {
|
func Merge(maps ...ResMap) (ResMap, error) {
|
||||||
result := ResMap{}
|
result := ResMap{}
|
||||||
for _, m := range maps {
|
for _, m := range maps {
|
||||||
for gvkn, obj := range m {
|
for id, obj := range m {
|
||||||
if _, found := result[gvkn]; found {
|
if _, found := result[id]; found {
|
||||||
return nil, fmt.Errorf("there is already an entry: %q", gvkn)
|
return nil, fmt.Errorf("there is already an entry: %q", id)
|
||||||
}
|
}
|
||||||
result[gvkn] = obj
|
result[id] = obj
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
const behaviorCreate = "create"
|
|
||||||
const behaviorReplace = "replace"
|
|
||||||
const behaviorMerge = "merge"
|
|
||||||
|
|
||||||
// MergeWithOverride merges the entries in the ResMap slice with Override.
|
// MergeWithOverride merges the entries in the ResMap slice with Override.
|
||||||
// If there is already an entry with the same Id , different actions are performed
|
// If there is already an entry with the same Id , different actions are performed
|
||||||
// according to value of behavior field:
|
// according to value of behavior field:
|
||||||
@@ -221,44 +215,30 @@ const behaviorMerge = "merge"
|
|||||||
func MergeWithOverride(maps ...ResMap) (ResMap, error) {
|
func MergeWithOverride(maps ...ResMap) (ResMap, error) {
|
||||||
result := ResMap{}
|
result := ResMap{}
|
||||||
for _, m := range maps {
|
for _, m := range maps {
|
||||||
for gvkn, resource := range m {
|
for id, r := range m {
|
||||||
if _, found := result[gvkn]; found {
|
if _, found := result[id]; found {
|
||||||
switch resource.Behavior() {
|
switch r.Behavior() {
|
||||||
case "", behaviorCreate:
|
case resource.BehaviorReplace:
|
||||||
return nil, fmt.Errorf("Create an existing gvkn %#v is not allowed", gvkn)
|
glog.V(4).Infof("Replace object %v by %v", result[id].Object, r.Object)
|
||||||
case behaviorReplace:
|
r.Replace(result[id])
|
||||||
glog.V(4).Infof("Replace object %v by %v", result[gvkn].Unstruct().Object, resource.Unstruct().Object)
|
result[id] = r
|
||||||
resource.Replace(result[gvkn])
|
case resource.BehaviorMerge:
|
||||||
result[gvkn] = resource
|
glog.V(4).Infof("Merge object %v with %v", result[id].Object, r.Object)
|
||||||
case behaviorMerge:
|
r.Merge(result[id])
|
||||||
glog.V(4).Infof("Merge object %v with %v", result[gvkn].Unstruct().Object, resource.Unstruct().Object)
|
result[id] = r
|
||||||
resource.Merge(result[gvkn])
|
glog.V(4).Infof("The merged object is %v", result[id].Object)
|
||||||
result[gvkn] = resource
|
|
||||||
glog.V(4).Infof("The merged object is %v", result[gvkn].Unstruct().Object)
|
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("The behavior of %#v must be one of merge and replace since it already exists in the base", gvkn)
|
return nil, fmt.Errorf("Id %#v exists; must merge or replace.", id)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
switch resource.Behavior() {
|
switch r.Behavior() {
|
||||||
case "", behaviorCreate:
|
case resource.BehaviorMerge, resource.BehaviorReplace:
|
||||||
result[gvkn] = resource
|
return nil, fmt.Errorf("Id %#v does not exist; cannot merge or replace.", id)
|
||||||
case behaviorMerge, behaviorReplace:
|
|
||||||
return nil, fmt.Errorf("No merge or replace is allowed for non existing gvkn %#v", gvkn)
|
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("The behavior of %#v must be create since it doesn't exist", gvkn)
|
result[id] = r
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func newUnstructuredFromObject(in runtime.Object) (*unstructured.Unstructured, error) {
|
|
||||||
marshaled, err := json.Marshal(in)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
var out unstructured.Unstructured
|
|
||||||
err = out.UnmarshalJSON(marshaled)
|
|
||||||
return &out, err
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -28,32 +28,34 @@ import (
|
|||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
func newFromSecretGenerator(p string, s types.SecretArgs) (*resource.Resource, error) {
|
func newResourceFromSecretGenerator(p string, sArgs types.SecretArgs) (*resource.Resource, error) {
|
||||||
corev1secret := &corev1.Secret{}
|
s, err := makeSecret(p, sArgs)
|
||||||
corev1secret.APIVersion = "v1"
|
if err != nil {
|
||||||
corev1secret.Kind = "Secret"
|
return nil, err
|
||||||
corev1secret.Name = s.Name
|
|
||||||
corev1secret.Type = corev1.SecretType(s.Type)
|
|
||||||
if corev1secret.Type == "" {
|
|
||||||
corev1secret.Type = corev1.SecretTypeOpaque
|
|
||||||
}
|
}
|
||||||
corev1secret.Data = map[string][]byte{}
|
return resource.NewResourceWithBehavior(
|
||||||
|
s, resource.NewGenerationBehavior(sArgs.Behavior))
|
||||||
|
}
|
||||||
|
|
||||||
for k, v := range s.Commands {
|
func makeSecret(p string, sArgs types.SecretArgs) (*corev1.Secret, error) {
|
||||||
|
s := &corev1.Secret{}
|
||||||
|
s.APIVersion = "v1"
|
||||||
|
s.Kind = "Secret"
|
||||||
|
s.Name = sArgs.Name
|
||||||
|
s.Type = corev1.SecretType(sArgs.Type)
|
||||||
|
if s.Type == "" {
|
||||||
|
s.Type = corev1.SecretTypeOpaque
|
||||||
|
}
|
||||||
|
s.Data = map[string][]byte{}
|
||||||
|
|
||||||
|
for k, v := range sArgs.Commands {
|
||||||
out, err := createSecretKey(p, v)
|
out, err := createSecretKey(p, v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
corev1secret.Data[k] = out
|
s.Data[k] = out
|
||||||
}
|
}
|
||||||
|
return s, nil
|
||||||
obj, err := newUnstructuredFromObject(corev1secret)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return resource.NewResource(obj, s.Behavior), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func createSecretKey(wd string, command string) ([]byte, error) {
|
func createSecretKey(wd string, command string) ([]byte, error) {
|
||||||
@@ -65,7 +67,6 @@ func createSecretKey(wd string, command string) ([]byte, error) {
|
|||||||
defer cancel()
|
defer cancel()
|
||||||
cmd := exec.CommandContext(ctx, "sh", "-c", command)
|
cmd := exec.CommandContext(ctx, "sh", "-c", command)
|
||||||
cmd.Dir = wd
|
cmd.Dir = wd
|
||||||
|
|
||||||
return cmd.Output()
|
return cmd.Output()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,7 +75,7 @@ func createSecretKey(wd string, command string) ([]byte, error) {
|
|||||||
func NewResMapFromSecretArgs(p string, secretList []types.SecretArgs) (ResMap, error) {
|
func NewResMapFromSecretArgs(p string, secretList []types.SecretArgs) (ResMap, error) {
|
||||||
allResources := []*resource.Resource{}
|
allResources := []*resource.Resource{}
|
||||||
for _, secret := range secretList {
|
for _, secret := range secretList {
|
||||||
res, err := newFromSecretGenerator(p, secret)
|
res, err := newResourceFromSecretGenerator(p, secret)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,10 +30,10 @@ import (
|
|||||||
|
|
||||||
var secret = schema.GroupVersionKind{Version: "v1", Kind: "Secret"}
|
var secret = schema.GroupVersionKind{Version: "v1", Kind: "Secret"}
|
||||||
|
|
||||||
func TestNewFromSecretGenerators(t *testing.T) {
|
func TestNewResMapFromSecretArgs(t *testing.T) {
|
||||||
secrets := []types.SecretArgs{
|
secrets := []types.SecretArgs{
|
||||||
{
|
{
|
||||||
Name: "secret",
|
Name: "apple",
|
||||||
Commands: map[string]string{
|
Commands: map[string]string{
|
||||||
"DB_USERNAME": "printf admin",
|
"DB_USERNAME": "printf admin",
|
||||||
"DB_PASSWORD": "printf somepw",
|
"DB_PASSWORD": "printf somepw",
|
||||||
@@ -41,19 +41,20 @@ func TestNewFromSecretGenerators(t *testing.T) {
|
|||||||
Type: "Opaque",
|
Type: "Opaque",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
re, err := NewResMapFromSecretArgs(".", secrets)
|
actual, err := NewResMapFromSecretArgs(".", secrets)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("unexpected error: %v", err)
|
t.Fatalf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
expected := ResMap{
|
expected := ResMap{
|
||||||
resource.NewResId(secret, "secret"): resource.NewResource(
|
resource.NewResId(secret, "apple"): resource.NewBehaviorlessResource(
|
||||||
&unstructured.Unstructured{
|
&unstructured.Unstructured{
|
||||||
Object: map[string]interface{}{
|
Object: map[string]interface{}{
|
||||||
"apiVersion": "v1",
|
"apiVersion": "v1",
|
||||||
"kind": "Secret",
|
"kind": "Secret",
|
||||||
"metadata": map[string]interface{}{
|
"metadata": map[string]interface{}{
|
||||||
"name": "secret",
|
"name": "apple",
|
||||||
"creationTimestamp": nil,
|
"creationTimestamp": nil,
|
||||||
},
|
},
|
||||||
"type": string(corev1.SecretTypeOpaque),
|
"type": string(corev1.SecretTypeOpaque),
|
||||||
@@ -62,11 +63,9 @@ func TestNewFromSecretGenerators(t *testing.T) {
|
|||||||
"DB_PASSWORD": base64.StdEncoding.EncodeToString([]byte("somepw")),
|
"DB_PASSWORD": base64.StdEncoding.EncodeToString([]byte("somepw")),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
}),
|
||||||
""),
|
|
||||||
}
|
}
|
||||||
|
if !reflect.DeepEqual(actual, expected) {
|
||||||
if !reflect.DeepEqual(re, expected) {
|
t.Fatalf("%#v\ndoesn't match expected:\n%#v", actual, expected)
|
||||||
t.Fatalf("%#v\ndoesn't match expected:\n%#v", re, expected)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
59
pkg/resource/generationbehavior.go
Normal file
59
pkg/resource/generationbehavior.go
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
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 resource
|
||||||
|
|
||||||
|
// GenerationBehavior specifies generation behavior of configmaps, secrets and maybe other resources.
|
||||||
|
type GenerationBehavior int
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Unspecified behavior typically treated as a Create.
|
||||||
|
BehaviorUnspecified GenerationBehavior = iota
|
||||||
|
// Make a new resource.
|
||||||
|
BehaviorCreate
|
||||||
|
// Replace a resource.
|
||||||
|
BehaviorReplace
|
||||||
|
// Attempt to merge a new resource with an existing resource.
|
||||||
|
BehaviorMerge
|
||||||
|
)
|
||||||
|
|
||||||
|
// String converts a GenerationBehavior to a string.
|
||||||
|
func (b GenerationBehavior) String() string {
|
||||||
|
switch b {
|
||||||
|
case BehaviorReplace:
|
||||||
|
return "replace"
|
||||||
|
case BehaviorMerge:
|
||||||
|
return "merge"
|
||||||
|
case BehaviorCreate:
|
||||||
|
return "create"
|
||||||
|
default:
|
||||||
|
return "unspecified"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewGenerationBehavior converts a string to a GenerationBehavior.
|
||||||
|
func NewGenerationBehavior(s string) GenerationBehavior {
|
||||||
|
switch s {
|
||||||
|
case "replace":
|
||||||
|
return BehaviorReplace
|
||||||
|
case "merge":
|
||||||
|
return BehaviorMerge
|
||||||
|
case "create":
|
||||||
|
return BehaviorCreate
|
||||||
|
default:
|
||||||
|
return BehaviorUnspecified
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -25,56 +25,49 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Resource is a Kubernetes Resource Object paired with a behavior.
|
// Resource is an "Unstructured" (json/map form) Kubernetes API resource object
|
||||||
|
// paired with a GenerationBehavior.
|
||||||
type Resource struct {
|
type Resource struct {
|
||||||
unstruct *unstructured.Unstructured
|
unstructured.Unstructured
|
||||||
behavior string
|
b GenerationBehavior
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewResource returns a new instance of Resource.
|
// NewResourceWithBehavior returns a new instance of Resource.
|
||||||
func NewResource(u *unstructured.Unstructured, b string) *Resource {
|
func NewResourceWithBehavior(obj runtime.Object, b GenerationBehavior) (*Resource, error) {
|
||||||
return &Resource{unstruct: u, behavior: b}
|
// Convert obj to a byte stream, then convert that to JSON (Unstructured).
|
||||||
|
marshaled, err := json.Marshal(obj)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var u unstructured.Unstructured
|
||||||
|
err = u.UnmarshalJSON(marshaled)
|
||||||
|
return &Resource{Unstructured: u, b: b}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewBehaviorlessResource returns a new instance of Resource.
|
// NewBehaviorlessResource returns a new instance of Resource.
|
||||||
func NewBehaviorlessResource(u *unstructured.Unstructured) *Resource {
|
func NewBehaviorlessResource(u *unstructured.Unstructured) *Resource {
|
||||||
return &Resource{unstruct: u}
|
return &Resource{Unstructured: *u, b: BehaviorUnspecified}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Behavior returns the behavior for the resource.
|
// Behavior returns the behavior for the resource.
|
||||||
func (r *Resource) Behavior() string {
|
func (r *Resource) Behavior() GenerationBehavior {
|
||||||
return r.behavior
|
return r.b
|
||||||
}
|
|
||||||
|
|
||||||
// Unstruct returns the unstructured object holding the resource.
|
|
||||||
func (r *Resource) Unstruct() *unstructured.Unstructured {
|
|
||||||
return r.unstruct
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetUnstruct sets a new member.
|
|
||||||
func (r *Resource) SetUnstruct(u *unstructured.Unstructured) {
|
|
||||||
r.unstruct = u
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Id returns the ResId for the resource.
|
// Id returns the ResId for the resource.
|
||||||
func (r *Resource) Id() ResId {
|
func (r *Resource) Id() ResId {
|
||||||
var empty ResId
|
return NewResId(r.GroupVersionKind(), r.GetName())
|
||||||
if r.unstruct == nil {
|
|
||||||
return empty
|
|
||||||
}
|
|
||||||
gvk := r.unstruct.GroupVersionKind()
|
|
||||||
return NewResId(gvk, r.unstruct.GetName())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Resource) Merge(other *Resource) {
|
func (r *Resource) Merge(other *Resource) {
|
||||||
r.Replace(other)
|
r.Replace(other)
|
||||||
mergeConfigmap(r.unstruct.Object, other.unstruct.Object, r.unstruct.Object)
|
mergeConfigmap(r.Object, other.Object, r.Object)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Resource) Replace(other *Resource) {
|
func (r *Resource) Replace(other *Resource) {
|
||||||
r.unstruct.SetLabels(mergeStringMaps(other.unstruct.GetLabels(), r.unstruct.GetLabels()))
|
r.SetLabels(mergeStringMaps(other.GetLabels(), r.GetLabels()))
|
||||||
r.unstruct.SetAnnotations(mergeStringMaps(other.unstruct.GetAnnotations(), r.unstruct.GetAnnotations()))
|
r.SetAnnotations(mergeStringMaps(other.GetAnnotations(), r.GetAnnotations()))
|
||||||
r.unstruct.SetName(other.unstruct.GetName())
|
r.SetName(other.GetName())
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Add BinaryData once we sync to new k8s.io/api
|
// TODO: Add BinaryData once we sync to new k8s.io/api
|
||||||
|
|||||||
@@ -57,8 +57,7 @@ func NewMapTransformer(pc []PathConfig, m map[string]string) (Transformer, error
|
|||||||
// fields specified in mapTransformer.
|
// fields specified in mapTransformer.
|
||||||
func (o *mapTransformer) Transform(m resmap.ResMap) error {
|
func (o *mapTransformer) Transform(m resmap.ResMap) error {
|
||||||
for id := range m {
|
for id := range m {
|
||||||
obj := m[id].Unstruct()
|
objMap := m[id].UnstructuredContent()
|
||||||
objMap := obj.UnstructuredContent()
|
|
||||||
for _, path := range o.pathConfigs {
|
for _, path := range o.pathConfigs {
|
||||||
if !selectByGVK(id.Gvk(), path.GroupVersionKind) {
|
if !selectByGVK(id.Gvk(), path.GroupVersionKind) {
|
||||||
continue
|
continue
|
||||||
|
|||||||
@@ -22,8 +22,8 @@ import (
|
|||||||
|
|
||||||
"github.com/kubernetes-sigs/kustomize/pkg/hash"
|
"github.com/kubernetes-sigs/kustomize/pkg/hash"
|
||||||
"github.com/kubernetes-sigs/kustomize/pkg/resmap"
|
"github.com/kubernetes-sigs/kustomize/pkg/resmap"
|
||||||
|
"github.com/kubernetes-sigs/kustomize/pkg/resource"
|
||||||
"k8s.io/api/core/v1"
|
"k8s.io/api/core/v1"
|
||||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -40,20 +40,20 @@ func NewNameHashTransformer() Transformer {
|
|||||||
|
|
||||||
// Transform appends hash to configmaps and secrets.
|
// Transform appends hash to configmaps and secrets.
|
||||||
func (o *nameHashTransformer) Transform(m resmap.ResMap) error {
|
func (o *nameHashTransformer) Transform(m resmap.ResMap) error {
|
||||||
for id, obj := range m {
|
for id, res := range m {
|
||||||
switch {
|
switch {
|
||||||
case selectByGVK(id.Gvk(), &schema.GroupVersionKind{Version: "v1", Kind: "ConfigMap"}):
|
case selectByGVK(id.Gvk(), &schema.GroupVersionKind{Version: "v1", Kind: "ConfigMap"}):
|
||||||
appendHashForConfigMap(obj.Unstruct())
|
appendHashForConfigMap(res)
|
||||||
|
|
||||||
case selectByGVK(id.Gvk(), &schema.GroupVersionKind{Version: "v1", Kind: "Secret"}):
|
case selectByGVK(id.Gvk(), &schema.GroupVersionKind{Version: "v1", Kind: "Secret"}):
|
||||||
appendHashForSecret(obj.Unstruct())
|
appendHashForSecret(res)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func appendHashForConfigMap(obj *unstructured.Unstructured) error {
|
func appendHashForConfigMap(res *resource.Resource) error {
|
||||||
cm, err := unstructuredToConfigmap(obj)
|
cm, err := unstructuredToConfigmap(res)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -61,14 +61,14 @@ func appendHashForConfigMap(obj *unstructured.Unstructured) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
nameWithHash := fmt.Sprintf("%s-%s", obj.GetName(), h)
|
nameWithHash := fmt.Sprintf("%s-%s", res.GetName(), h)
|
||||||
obj.SetName(nameWithHash)
|
res.SetName(nameWithHash)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Remove this function after we support hash unstructured objects
|
// TODO: Remove this function after we support hash unstructured objects
|
||||||
func unstructuredToConfigmap(in *unstructured.Unstructured) (*v1.ConfigMap, error) {
|
func unstructuredToConfigmap(res *resource.Resource) (*v1.ConfigMap, error) {
|
||||||
marshaled, err := json.Marshal(in)
|
marshaled, err := json.Marshal(res)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -77,8 +77,8 @@ func unstructuredToConfigmap(in *unstructured.Unstructured) (*v1.ConfigMap, erro
|
|||||||
return &out, err
|
return &out, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func appendHashForSecret(obj *unstructured.Unstructured) error {
|
func appendHashForSecret(res *resource.Resource) error {
|
||||||
secret, err := unstructuredToSecret(obj)
|
secret, err := unstructuredToSecret(res)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -86,14 +86,14 @@ func appendHashForSecret(obj *unstructured.Unstructured) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
nameWithHash := fmt.Sprintf("%s-%s", obj.GetName(), h)
|
nameWithHash := fmt.Sprintf("%s-%s", res.GetName(), h)
|
||||||
obj.SetName(nameWithHash)
|
res.SetName(nameWithHash)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Remove this function after we support hash unstructured objects
|
// TODO: Remove this function after we support hash unstructured objects
|
||||||
func unstructuredToSecret(in *unstructured.Unstructured) (*v1.Secret, error) {
|
func unstructuredToSecret(res *resource.Resource) (*v1.Secret, error) {
|
||||||
marshaled, err := json.Marshal(in)
|
marshaled, err := json.Marshal(res)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,11 +49,9 @@ func NewNameReferenceTransformer(pc []referencePathConfig) (Transformer, error)
|
|||||||
// The old name is in the key in the map and the new name is in the object
|
// The old name is in the key in the map and the new name is in the object
|
||||||
// associated with the key. e.g. if <k, v> is one of the key-value pair in the map,
|
// associated with the key. e.g. if <k, v> is one of the key-value pair in the map,
|
||||||
// then the old name is k.Name and the new name is v.GetName()
|
// then the old name is k.Name and the new name is v.GetName()
|
||||||
func (o *nameReferenceTransformer) Transform(
|
func (o *nameReferenceTransformer) Transform(m resmap.ResMap) error {
|
||||||
m resmap.ResMap) error {
|
|
||||||
for id := range m {
|
for id := range m {
|
||||||
obj := m[id].Unstruct()
|
objMap := m[id].UnstructuredContent()
|
||||||
objMap := obj.UnstructuredContent()
|
|
||||||
for _, referencePathConfig := range o.pathConfigs {
|
for _, referencePathConfig := range o.pathConfigs {
|
||||||
for _, path := range referencePathConfig.pathConfigs {
|
for _, path := range referencePathConfig.pathConfigs {
|
||||||
if !selectByGVK(id.Gvk(), path.GroupVersionKind) {
|
if !selectByGVK(id.Gvk(), path.GroupVersionKind) {
|
||||||
@@ -71,21 +69,19 @@ func (o *nameReferenceTransformer) Transform(
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (o *nameReferenceTransformer) updateNameReference(
|
func (o *nameReferenceTransformer) updateNameReference(
|
||||||
GVK schema.GroupVersionKind,
|
GVK schema.GroupVersionKind, m resmap.ResMap) func(in interface{}) (interface{}, error) {
|
||||||
m resmap.ResMap,
|
|
||||||
) func(in interface{}) (interface{}, error) {
|
|
||||||
return func(in interface{}) (interface{}, error) {
|
return func(in interface{}) (interface{}, error) {
|
||||||
s, ok := in.(string)
|
s, ok := in.(string)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("%#v is expectd to be %T", in, s)
|
return nil, fmt.Errorf("%#v is expectd to be %T", in, s)
|
||||||
}
|
}
|
||||||
|
|
||||||
for id, obj := range m {
|
for id, res := range m {
|
||||||
if !selectByGVK(id.Gvk(), &GVK) {
|
if !selectByGVK(id.Gvk(), &GVK) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if id.Name() == s {
|
if id.Name() == s {
|
||||||
return obj.Unstruct().GetName(), nil
|
return res.GetName(), nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return in, nil
|
return in, nil
|
||||||
|
|||||||
@@ -36,8 +36,8 @@ func NewNamespaceTransformer(ns string) Transformer {
|
|||||||
|
|
||||||
// Transform adds the namespace.
|
// Transform adds the namespace.
|
||||||
func (o *namespaceTransformer) Transform(m resmap.ResMap) error {
|
func (o *namespaceTransformer) Transform(m resmap.ResMap) error {
|
||||||
for _, obj := range m {
|
for _, res := range m {
|
||||||
obj.Unstruct().SetNamespace(o.namespace)
|
res.SetNamespace(o.namespace)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ import (
|
|||||||
|
|
||||||
"github.com/kubernetes-sigs/kustomize/pkg/resmap"
|
"github.com/kubernetes-sigs/kustomize/pkg/resmap"
|
||||||
"github.com/kubernetes-sigs/kustomize/pkg/resource"
|
"github.com/kubernetes-sigs/kustomize/pkg/resource"
|
||||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/util/strategicpatch"
|
"k8s.io/apimachinery/pkg/util/strategicpatch"
|
||||||
"k8s.io/client-go/kubernetes/scheme"
|
"k8s.io/client-go/kubernetes/scheme"
|
||||||
@@ -63,15 +62,15 @@ func (o *overlayTransformer) Transform(baseResourceMap resmap.ResMap) error {
|
|||||||
}
|
}
|
||||||
merged := map[string]interface{}{}
|
merged := map[string]interface{}{}
|
||||||
versionedObj, err := scheme.Scheme.New(id.Gvk())
|
versionedObj, err := scheme.Scheme.New(id.Gvk())
|
||||||
baseName := base.Unstruct().GetName()
|
baseName := base.GetName()
|
||||||
switch {
|
switch {
|
||||||
case runtime.IsNotRegisteredError(err):
|
case runtime.IsNotRegisteredError(err):
|
||||||
// Use JSON merge patch to handle types w/o schema
|
// Use JSON merge patch to handle types w/o schema
|
||||||
baseBytes, err := json.Marshal(base.Unstruct())
|
baseBytes, err := json.Marshal(base)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
patchBytes, err := json.Marshal(overlay.Unstruct())
|
patchBytes, err := json.Marshal(overlay)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -95,15 +94,15 @@ func (o *overlayTransformer) Transform(baseResourceMap resmap.ResMap) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
merged, err = strategicpatch.StrategicMergeMapPatchUsingLookupPatchMeta(
|
merged, err = strategicpatch.StrategicMergeMapPatchUsingLookupPatchMeta(
|
||||||
base.Unstruct().Object,
|
base.Object,
|
||||||
overlay.Unstruct().Object,
|
overlay.Object,
|
||||||
lookupPatchMeta)
|
lookupPatchMeta)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
base.Unstruct().SetName(baseName)
|
base.SetName(baseName)
|
||||||
baseResourceMap[id].Unstruct().Object = merged
|
baseResourceMap[id].Object = merged
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -112,7 +111,6 @@ func (o *overlayTransformer) Transform(baseResourceMap resmap.ResMap) error {
|
|||||||
// It errors out if there is conflict between patches.
|
// It errors out if there is conflict between patches.
|
||||||
func (o *overlayTransformer) mergePatches() (resmap.ResMap, error) {
|
func (o *overlayTransformer) mergePatches() (resmap.ResMap, error) {
|
||||||
rc := resmap.ResMap{}
|
rc := resmap.ResMap{}
|
||||||
patches := resourcesToObjects(o.overlay)
|
|
||||||
for ix, patch := range o.overlay {
|
for ix, patch := range o.overlay {
|
||||||
id := patch.Id()
|
id := patch.Id()
|
||||||
existing, found := rc[id]
|
existing, found := rc[id]
|
||||||
@@ -135,31 +133,22 @@ func (o *overlayTransformer) mergePatches() (resmap.ResMap, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
conflict, err := cd.hasConflict(existing.Unstruct(), patch.Unstruct())
|
conflict, err := cd.hasConflict(existing, patch)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if conflict {
|
if conflict {
|
||||||
conflictingPatch, err := cd.findConflict(ix, patches)
|
conflictingPatch, err := cd.findConflict(ix, o.overlay)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return nil, fmt.Errorf("there is conflict between %#v and %#v", conflictingPatch.Object, patch.Unstruct().Object)
|
return nil, fmt.Errorf("there is conflict between %#v and %#v", conflictingPatch.Object, patch.Object)
|
||||||
} else {
|
|
||||||
merged, err := cd.mergePatches(existing.Unstruct(), patch.Unstruct())
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
existing.SetUnstruct(merged)
|
|
||||||
}
|
}
|
||||||
|
merged, err := cd.mergePatches(existing, patch)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
rc[id] = merged
|
||||||
}
|
}
|
||||||
return rc, nil
|
return rc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func resourcesToObjects(rs []*resource.Resource) []*unstructured.Unstructured {
|
|
||||||
objectList := make([]*unstructured.Unstructured, len(rs))
|
|
||||||
for i := range rs {
|
|
||||||
objectList[i] = rs[i].Unstruct()
|
|
||||||
}
|
|
||||||
return objectList
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -19,18 +19,18 @@ package transformers
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
|
||||||
jsonpatch "github.com/evanphx/json-patch"
|
"github.com/evanphx/json-patch"
|
||||||
|
|
||||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
"github.com/kubernetes-sigs/kustomize/pkg/resource"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/util/mergepatch"
|
"k8s.io/apimachinery/pkg/util/mergepatch"
|
||||||
"k8s.io/apimachinery/pkg/util/strategicpatch"
|
"k8s.io/apimachinery/pkg/util/strategicpatch"
|
||||||
)
|
)
|
||||||
|
|
||||||
type conflictDetector interface {
|
type conflictDetector interface {
|
||||||
hasConflict(patch1, patch2 *unstructured.Unstructured) (bool, error)
|
hasConflict(patch1, patch2 *resource.Resource) (bool, error)
|
||||||
findConflict(conflictingPatchIdx int, patches []*unstructured.Unstructured) (*unstructured.Unstructured, error)
|
findConflict(conflictingPatchIdx int, patches []*resource.Resource) (*resource.Resource, error)
|
||||||
mergePatches(patch1, patch2 *unstructured.Unstructured) (*unstructured.Unstructured, error)
|
mergePatches(patch1, patch2 *resource.Resource) (*resource.Resource, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type jsonMergePatch struct{}
|
type jsonMergePatch struct{}
|
||||||
@@ -41,11 +41,11 @@ func newJMPConflictDetector() conflictDetector {
|
|||||||
return &jsonMergePatch{}
|
return &jsonMergePatch{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (jmp *jsonMergePatch) hasConflict(patch1, patch2 *unstructured.Unstructured) (bool, error) {
|
func (jmp *jsonMergePatch) hasConflict(patch1, patch2 *resource.Resource) (bool, error) {
|
||||||
return mergepatch.HasConflicts(patch1.Object, patch2.Object)
|
return mergepatch.HasConflicts(patch1.Object, patch2.Object)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (jmp *jsonMergePatch) findConflict(conflictingPatchIdx int, patches []*unstructured.Unstructured) (*unstructured.Unstructured, error) {
|
func (jmp *jsonMergePatch) findConflict(conflictingPatchIdx int, patches []*resource.Resource) (*resource.Resource, error) {
|
||||||
for i, patch := range patches {
|
for i, patch := range patches {
|
||||||
if i == conflictingPatchIdx {
|
if i == conflictingPatchIdx {
|
||||||
continue
|
continue
|
||||||
@@ -65,8 +65,8 @@ func (jmp *jsonMergePatch) findConflict(conflictingPatchIdx int, patches []*unst
|
|||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (jmp *jsonMergePatch) mergePatches(patch1, patch2 *unstructured.Unstructured) (*unstructured.Unstructured, error) {
|
func (jmp *jsonMergePatch) mergePatches(patch1, patch2 *resource.Resource) (*resource.Resource, error) {
|
||||||
var merged unstructured.Unstructured
|
var merged resource.Resource
|
||||||
var mergedMap map[string]interface{}
|
var mergedMap map[string]interface{}
|
||||||
baseBytes, err := json.Marshal(patch1.Object)
|
baseBytes, err := json.Marshal(patch1.Object)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -96,11 +96,11 @@ func newSMPConflictDetector(versionedObj runtime.Object) (conflictDetector, erro
|
|||||||
return &strategicMergePatch{lookupPatchMeta: lookupPatchMeta}, err
|
return &strategicMergePatch{lookupPatchMeta: lookupPatchMeta}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (smp *strategicMergePatch) hasConflict(patch1, patch2 *unstructured.Unstructured) (bool, error) {
|
func (smp *strategicMergePatch) hasConflict(patch1, patch2 *resource.Resource) (bool, error) {
|
||||||
return strategicpatch.MergingMapsHaveConflicts(patch1.Object, patch2.Object, smp.lookupPatchMeta)
|
return strategicpatch.MergingMapsHaveConflicts(patch1.Object, patch2.Object, smp.lookupPatchMeta)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (smp *strategicMergePatch) findConflict(conflictingPatchIdx int, patches []*unstructured.Unstructured) (*unstructured.Unstructured, error) {
|
func (smp *strategicMergePatch) findConflict(conflictingPatchIdx int, patches []*resource.Resource) (*resource.Resource, error) {
|
||||||
for i, patch := range patches {
|
for i, patch := range patches {
|
||||||
if i == conflictingPatchIdx {
|
if i == conflictingPatchIdx {
|
||||||
continue
|
continue
|
||||||
@@ -121,8 +121,8 @@ func (smp *strategicMergePatch) findConflict(conflictingPatchIdx int, patches []
|
|||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (smp *strategicMergePatch) mergePatches(patch1, patch2 *unstructured.Unstructured) (*unstructured.Unstructured, error) {
|
func (smp *strategicMergePatch) mergePatches(patch1, patch2 *resource.Resource) (*resource.Resource, error) {
|
||||||
merged := unstructured.Unstructured{}
|
merged := resource.Resource{}
|
||||||
mergeJsonMap, err := strategicpatch.MergeStrategicMergeMapPatchUsingLookupPatchMeta(
|
mergeJsonMap, err := strategicpatch.MergeStrategicMergeMapPatchUsingLookupPatchMeta(
|
||||||
smp.lookupPatchMeta, patch1.Object, patch2.Object)
|
smp.lookupPatchMeta, patch1.Object, patch2.Object)
|
||||||
merged.SetUnstructuredContent(mergeJsonMap)
|
merged.SetUnstructuredContent(mergeJsonMap)
|
||||||
|
|||||||
@@ -58,8 +58,7 @@ func NewNamePrefixTransformer(pc []PathConfig, np string) (Transformer, error) {
|
|||||||
// Transform prepends the name prefix.
|
// Transform prepends the name prefix.
|
||||||
func (o *namePrefixTransformer) Transform(m resmap.ResMap) error {
|
func (o *namePrefixTransformer) Transform(m resmap.ResMap) error {
|
||||||
for id := range m {
|
for id := range m {
|
||||||
obj := m[id].Unstruct()
|
objMap := m[id].UnstructuredContent()
|
||||||
objMap := obj.UnstructuredContent()
|
|
||||||
for _, path := range o.pathConfigs {
|
for _, path := range o.pathConfigs {
|
||||||
if !selectByGVK(id.Gvk(), path.GroupVersionKind) {
|
if !selectByGVK(id.Gvk(), path.GroupVersionKind) {
|
||||||
continue
|
continue
|
||||||
|
|||||||
@@ -45,8 +45,7 @@ func NewRefVarTransformer(vars map[string]string) (Transformer, error) {
|
|||||||
// 3. Add remaining service environment vars
|
// 3. Add remaining service environment vars
|
||||||
func (rv *refvarTransformer) Transform(resources resmap.ResMap) error {
|
func (rv *refvarTransformer) Transform(resources resmap.ResMap) error {
|
||||||
for GVKn := range resources {
|
for GVKn := range resources {
|
||||||
obj := resources[GVKn].Unstruct()
|
objMap := resources[GVKn].UnstructuredContent()
|
||||||
objMap := obj.UnstructuredContent()
|
|
||||||
for _, pc := range rv.pathConfigs {
|
for _, pc := range rv.pathConfigs {
|
||||||
if !selectByGVK(GVKn.Gvk(), pc.GroupVersionKind) {
|
if !selectByGVK(GVKn.Gvk(), pc.GroupVersionKind) {
|
||||||
continue
|
continue
|
||||||
|
|||||||
Reference in New Issue
Block a user