mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-06-14 10:30:59 +00:00
add inline patch support for Strategic Merge Patch and JSON patch
This commit is contained in:
243
pkg/target/inlinepatch_test.go
Normal file
243
pkg/target/inlinepatch_test.go
Normal file
@@ -0,0 +1,243 @@
|
|||||||
|
// Copyright 2019 The Kubernetes Authors.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
package target_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sigs.k8s.io/kustomize/v3/pkg/kusttest"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func makeResourcesForPatchTest(th *kusttest_test.KustTestHarness) {
|
||||||
|
th.WriteF("/app/base/deployment.yaml", `
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: nginx
|
||||||
|
labels:
|
||||||
|
app: nginx
|
||||||
|
spec:
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: nginx
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: nginx
|
||||||
|
image: nginx
|
||||||
|
volumeMounts:
|
||||||
|
- name: nginx-persistent-storage
|
||||||
|
mountPath: /tmp/ps
|
||||||
|
volumes:
|
||||||
|
- name: nginx-persistent-storage
|
||||||
|
emptyDir: {}
|
||||||
|
- configMap:
|
||||||
|
name: configmap-in-base
|
||||||
|
name: configmap-in-base
|
||||||
|
`)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestStrategicMergePatchInline(t *testing.T) {
|
||||||
|
th := kusttest_test.NewKustTestHarness(t, "/app/base")
|
||||||
|
makeResourcesForPatchTest(th)
|
||||||
|
th.WriteK("/app/base", `
|
||||||
|
resources:
|
||||||
|
- deployment.yaml
|
||||||
|
|
||||||
|
patchesStrategicMerge:
|
||||||
|
- |-
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: nginx
|
||||||
|
spec:
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: nginx
|
||||||
|
image: image1
|
||||||
|
`)
|
||||||
|
m, err := th.MakeKustTarget().MakeCustomizedResMap()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Err: %v", err)
|
||||||
|
}
|
||||||
|
th.AssertActualEqualsExpected(m, `
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: nginx
|
||||||
|
name: nginx
|
||||||
|
spec:
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: nginx
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- image: image1
|
||||||
|
name: nginx
|
||||||
|
volumeMounts:
|
||||||
|
- mountPath: /tmp/ps
|
||||||
|
name: nginx-persistent-storage
|
||||||
|
volumes:
|
||||||
|
- emptyDir: {}
|
||||||
|
name: nginx-persistent-storage
|
||||||
|
- configMap:
|
||||||
|
name: configmap-in-base
|
||||||
|
name: configmap-in-base
|
||||||
|
`)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestJSONPatchInline(t *testing.T) {
|
||||||
|
th := kusttest_test.NewKustTestHarness(t, "/app/base")
|
||||||
|
makeResourcesForPatchTest(th)
|
||||||
|
th.WriteK("/app/base", `
|
||||||
|
resources:
|
||||||
|
- deployment.yaml
|
||||||
|
|
||||||
|
patchesJson6902:
|
||||||
|
- target:
|
||||||
|
group: apps
|
||||||
|
version: v1
|
||||||
|
kind: Deployment
|
||||||
|
name: nginx
|
||||||
|
patch: |-
|
||||||
|
- op: replace
|
||||||
|
path: /spec/template/spec/containers/0/image
|
||||||
|
value: image1
|
||||||
|
`)
|
||||||
|
m, err := th.MakeKustTarget().MakeCustomizedResMap()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Err: %v", err)
|
||||||
|
}
|
||||||
|
th.AssertActualEqualsExpected(m, `
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: nginx
|
||||||
|
name: nginx
|
||||||
|
spec:
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: nginx
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- image: image1
|
||||||
|
name: nginx
|
||||||
|
volumeMounts:
|
||||||
|
- mountPath: /tmp/ps
|
||||||
|
name: nginx-persistent-storage
|
||||||
|
volumes:
|
||||||
|
- emptyDir: {}
|
||||||
|
name: nginx-persistent-storage
|
||||||
|
- configMap:
|
||||||
|
name: configmap-in-base
|
||||||
|
name: configmap-in-base
|
||||||
|
`)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestExtendedPatchInlineJSON(t *testing.T) {
|
||||||
|
th := kusttest_test.NewKustTestHarness(t, "/app/base")
|
||||||
|
makeResourcesForPatchTest(th)
|
||||||
|
th.WriteK("/app/base", `
|
||||||
|
resources:
|
||||||
|
- deployment.yaml
|
||||||
|
|
||||||
|
patches:
|
||||||
|
- target:
|
||||||
|
kind: Deployment
|
||||||
|
name: nginx
|
||||||
|
patch: |-
|
||||||
|
- op: replace
|
||||||
|
path: /spec/template/spec/containers/0/image
|
||||||
|
value: image1
|
||||||
|
`)
|
||||||
|
m, err := th.MakeKustTarget().MakeCustomizedResMap()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Err: %v", err)
|
||||||
|
}
|
||||||
|
th.AssertActualEqualsExpected(m, `
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: nginx
|
||||||
|
name: nginx
|
||||||
|
spec:
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: nginx
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- image: image1
|
||||||
|
name: nginx
|
||||||
|
volumeMounts:
|
||||||
|
- mountPath: /tmp/ps
|
||||||
|
name: nginx-persistent-storage
|
||||||
|
volumes:
|
||||||
|
- emptyDir: {}
|
||||||
|
name: nginx-persistent-storage
|
||||||
|
- configMap:
|
||||||
|
name: configmap-in-base
|
||||||
|
name: configmap-in-base
|
||||||
|
`)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestExtendedPatchInlineYAML(t *testing.T) {
|
||||||
|
th := kusttest_test.NewKustTestHarness(t, "/app/base")
|
||||||
|
makeResourcesForPatchTest(th)
|
||||||
|
th.WriteK("/app/base", `
|
||||||
|
resources:
|
||||||
|
- deployment.yaml
|
||||||
|
|
||||||
|
patches:
|
||||||
|
- target:
|
||||||
|
kind: Deployment
|
||||||
|
name: nginx
|
||||||
|
patch: |-
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: nginx
|
||||||
|
spec:
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: nginx
|
||||||
|
image: image1
|
||||||
|
`)
|
||||||
|
m, err := th.MakeKustTarget().MakeCustomizedResMap()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Err: %v", err)
|
||||||
|
}
|
||||||
|
th.AssertActualEqualsExpected(m, `
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: nginx
|
||||||
|
name: nginx
|
||||||
|
spec:
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: nginx
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- image: image1
|
||||||
|
name: nginx
|
||||||
|
volumeMounts:
|
||||||
|
- mountPath: /tmp/ps
|
||||||
|
name: nginx-persistent-storage
|
||||||
|
volumes:
|
||||||
|
- emptyDir: {}
|
||||||
|
name: nginx-persistent-storage
|
||||||
|
- configMap:
|
||||||
|
name: configmap-in-base
|
||||||
|
name: configmap-in-base
|
||||||
|
`)
|
||||||
|
}
|
||||||
@@ -156,7 +156,7 @@ func (kt *KustTarget) configureBuiltinPatchJson6902Transformer(
|
|||||||
for _, args := range kt.kustomization.PatchesJson6902 {
|
for _, args := range kt.kustomization.PatchesJson6902 {
|
||||||
c.Target = *args.Target
|
c.Target = *args.Target
|
||||||
c.Path = args.Path
|
c.Path = args.Path
|
||||||
c.JsonOp = "" // Not implemented for kustomization file yet.
|
c.JsonOp = args.Patch
|
||||||
p := builtin.NewPatchJson6902TransformerPlugin()
|
p := builtin.NewPatchJson6902TransformerPlugin()
|
||||||
err = kt.configureBuiltinPlugin(p, c, "patchJson6902")
|
err = kt.configureBuiltinPlugin(p, c, "patchJson6902")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -178,7 +178,6 @@ func (kt *KustTarget) configureBuiltinPatchStrategicMergeTransformer(
|
|||||||
Patches string `json:"patches,omitempty" yaml:"patches,omitempty"`
|
Patches string `json:"patches,omitempty" yaml:"patches,omitempty"`
|
||||||
}
|
}
|
||||||
c.Paths = kt.kustomization.PatchesStrategicMerge
|
c.Paths = kt.kustomization.PatchesStrategicMerge
|
||||||
c.Patches = "" // Not implemented for kustomization file yet
|
|
||||||
p := builtin.NewPatchStrategicMergeTransformerPlugin()
|
p := builtin.NewPatchStrategicMergeTransformerPlugin()
|
||||||
err = kt.configureBuiltinPlugin(p, c, "patchStrategicMerge")
|
err = kt.configureBuiltinPlugin(p, c, "patchStrategicMerge")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -331,6 +331,9 @@ type PatchJson6902 struct {
|
|||||||
|
|
||||||
// relative file path for a json patch file inside a kustomization
|
// relative file path for a json patch file inside a kustomization
|
||||||
Path string `json:"path,omitempty" yaml:"path,omitempty"`
|
Path string `json:"path,omitempty" yaml:"path,omitempty"`
|
||||||
|
|
||||||
|
// inline patch string
|
||||||
|
Patch string `json:"patch,omitempty" yaml:"patch,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// PatchTarget represents the kubernetes object that the patch is applied to
|
// PatchTarget represents the kubernetes object that the patch is applied to
|
||||||
|
|||||||
@@ -35,11 +35,18 @@ func (p *PatchStrategicMergeTransformerPlugin) Config(
|
|||||||
return fmt.Errorf("empty file path and empty patch content")
|
return fmt.Errorf("empty file path and empty patch content")
|
||||||
}
|
}
|
||||||
if len(p.Paths) != 0 {
|
if len(p.Paths) != 0 {
|
||||||
res, err := p.rf.RF().SliceFromPatches(ldr, p.Paths)
|
for _, onePath := range p.Paths {
|
||||||
if err != nil {
|
res, err := p.rf.RF().SliceFromBytes([]byte(onePath))
|
||||||
return err
|
if err == nil {
|
||||||
|
p.loadedPatches = append(p.loadedPatches, res...)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
res, err = p.rf.RF().SliceFromPatches(ldr, []types.PatchStrategicMerge{onePath})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
p.loadedPatches = append(p.loadedPatches, res...)
|
||||||
}
|
}
|
||||||
p.loadedPatches = res
|
|
||||||
}
|
}
|
||||||
if p.Patches != "" {
|
if p.Patches != "" {
|
||||||
res, err := p.rf.RF().SliceFromBytes([]byte(p.Patches))
|
res, err := p.rf.RF().SliceFromBytes([]byte(p.Patches))
|
||||||
|
|||||||
@@ -36,11 +36,18 @@ func (p *plugin) Config(
|
|||||||
return fmt.Errorf("empty file path and empty patch content")
|
return fmt.Errorf("empty file path and empty patch content")
|
||||||
}
|
}
|
||||||
if len(p.Paths) != 0 {
|
if len(p.Paths) != 0 {
|
||||||
res, err := p.rf.RF().SliceFromPatches(ldr, p.Paths)
|
for _, onePath := range p.Paths {
|
||||||
if err != nil {
|
res, err := p.rf.RF().SliceFromBytes([]byte(onePath))
|
||||||
return err
|
if err == nil {
|
||||||
|
p.loadedPatches = append(p.loadedPatches, res...)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
res, err = p.rf.RF().SliceFromPatches(ldr, []types.PatchStrategicMerge{onePath})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
p.loadedPatches = append(p.loadedPatches, res...)
|
||||||
}
|
}
|
||||||
p.loadedPatches = res
|
|
||||||
}
|
}
|
||||||
if p.Patches != "" {
|
if p.Patches != "" {
|
||||||
res, err := p.rf.RF().SliceFromBytes([]byte(p.Patches))
|
res, err := p.rf.RF().SliceFromBytes([]byte(p.Patches))
|
||||||
|
|||||||
@@ -78,7 +78,9 @@ paths:
|
|||||||
t.Fatalf("expected error")
|
t.Fatalf("expected error")
|
||||||
}
|
}
|
||||||
if !strings.Contains(err.Error(),
|
if !strings.Contains(err.Error(),
|
||||||
"cannot read file \"/app/patch.yaml\"") {
|
"cannot read file \"/app/patch.yaml\"") &&
|
||||||
|
!strings.Contains(err.Error(),
|
||||||
|
"cannot unmarshal string") {
|
||||||
t.Fatalf("unexpected err: %v", err)
|
t.Fatalf("unexpected err: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user