add inline patch support for Strategic Merge Patch and JSON patch

This commit is contained in:
jingfangliu
2019-07-26 17:00:41 -07:00
parent a9848f2738
commit 35481ec6d9
6 changed files with 273 additions and 12 deletions

View 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
`)
}

View File

@@ -156,7 +156,7 @@ func (kt *KustTarget) configureBuiltinPatchJson6902Transformer(
for _, args := range kt.kustomization.PatchesJson6902 {
c.Target = *args.Target
c.Path = args.Path
c.JsonOp = "" // Not implemented for kustomization file yet.
c.JsonOp = args.Patch
p := builtin.NewPatchJson6902TransformerPlugin()
err = kt.configureBuiltinPlugin(p, c, "patchJson6902")
if err != nil {
@@ -178,7 +178,6 @@ func (kt *KustTarget) configureBuiltinPatchStrategicMergeTransformer(
Patches string `json:"patches,omitempty" yaml:"patches,omitempty"`
}
c.Paths = kt.kustomization.PatchesStrategicMerge
c.Patches = "" // Not implemented for kustomization file yet
p := builtin.NewPatchStrategicMergeTransformerPlugin()
err = kt.configureBuiltinPlugin(p, c, "patchStrategicMerge")
if err != nil {

View File

@@ -331,6 +331,9 @@ type PatchJson6902 struct {
// relative file path for a json patch file inside a kustomization
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

View File

@@ -35,11 +35,18 @@ func (p *PatchStrategicMergeTransformerPlugin) Config(
return fmt.Errorf("empty file path and empty patch content")
}
if len(p.Paths) != 0 {
res, err := p.rf.RF().SliceFromPatches(ldr, p.Paths)
if err != nil {
return err
for _, onePath := range p.Paths {
res, err := p.rf.RF().SliceFromBytes([]byte(onePath))
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 != "" {
res, err := p.rf.RF().SliceFromBytes([]byte(p.Patches))

View File

@@ -36,11 +36,18 @@ func (p *plugin) Config(
return fmt.Errorf("empty file path and empty patch content")
}
if len(p.Paths) != 0 {
res, err := p.rf.RF().SliceFromPatches(ldr, p.Paths)
if err != nil {
return err
for _, onePath := range p.Paths {
res, err := p.rf.RF().SliceFromBytes([]byte(onePath))
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 != "" {
res, err := p.rf.RF().SliceFromBytes([]byte(p.Patches))

View File

@@ -78,7 +78,9 @@ paths:
t.Fatalf("expected 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)
}
}
@@ -1278,4 +1280,4 @@ paths:
`, target)
th.AssertActualEqualsExpected(rm, ``)
}
}