mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-06-15 02:48:16 +00:00
Compare commits
25 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c464fb0a81 | ||
|
|
694cf23df8 | ||
|
|
e66656aa7f | ||
|
|
eaae7af5fe | ||
|
|
f9fe138114 | ||
|
|
2a2a889c37 | ||
|
|
34287e511f | ||
|
|
e6fffc8ba4 | ||
|
|
86f221611e | ||
|
|
b4d6e89fa2 | ||
|
|
5937bd0259 | ||
|
|
ed3c29be12 | ||
|
|
3d2e956b19 | ||
|
|
dd9d1f95e9 | ||
|
|
a279c08f7d | ||
|
|
a798109161 | ||
|
|
bafd6b5423 | ||
|
|
963913f9ef | ||
|
|
46905588ac | ||
|
|
5426888df4 | ||
|
|
35481ec6d9 | ||
|
|
6c92c30e94 | ||
|
|
02f6b3ec98 | ||
|
|
a9848f2738 | ||
|
|
b4038a6cd2 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -4,6 +4,7 @@
|
||||
*.dll
|
||||
*.so
|
||||
*.dylib
|
||||
/kustomize
|
||||
|
||||
# Test binary, build with `go test -c`
|
||||
*.test
|
||||
|
||||
28
Makefile
Normal file
28
Makefile
Normal file
@@ -0,0 +1,28 @@
|
||||
BIN_NAME=kustomize
|
||||
|
||||
export GO111MODULE=on
|
||||
|
||||
all: test build
|
||||
|
||||
test: generate-code test-lint test-go
|
||||
|
||||
test-go:
|
||||
go test -v ./...
|
||||
|
||||
test-lint:
|
||||
golangci-lint run ./...
|
||||
|
||||
generate-code:
|
||||
./plugin/generateBuiltins.sh $(GOPATH)
|
||||
|
||||
build:
|
||||
go build -o $(BIN_NAME) cmd/kustomize/main.go
|
||||
|
||||
install:
|
||||
go install $(PWD)/cmd/kustomize
|
||||
|
||||
clean:
|
||||
go clean
|
||||
rm -f $(BIN_NAME)
|
||||
|
||||
.PHONY: test build install clean generate-code test-go test-lint
|
||||
14
README.md
14
README.md
@@ -24,8 +24,16 @@ these [instructions](docs/INSTALL.md).
|
||||
Browse the [docs](docs) or jump right into the
|
||||
tested [examples](examples).
|
||||
|
||||
kustomize [v2.0.3] is available in [kubectl v1.14 and v1.15][kubectl].
|
||||
## kubectl integration
|
||||
|
||||
Since [v1.14][kubectl announcement] the kustomize build system has been included in kubectl.
|
||||
|
||||
| kubectl version | kustomize version |
|
||||
|---------|--------|
|
||||
| v1.15.x | [v2.0.3](https://github.com/kubernetes-sigs/kustomize/tree/v2.0.3) |
|
||||
| v1.14.x | [v2.0.3](https://github.com/kubernetes-sigs/kustomize/tree/v2.0.3) |
|
||||
|
||||
For examples and guides for using the kubectl integration please see the [kubectl book] or the [kubernetes documentation].
|
||||
|
||||
## Usage
|
||||
|
||||
@@ -161,7 +169,9 @@ is governed by the [Kubernetes Code of Conduct].
|
||||
[imageBase]: docs/images/base.jpg
|
||||
[imageOverlay]: docs/images/overlay.jpg
|
||||
[kind/feature]: https://github.com/kubernetes-sigs/kustomize/labels/kind%2Ffeature
|
||||
[kubectl]: https://kubernetes.io/blog/2019/03/25/kubernetes-1-14-release-announcement
|
||||
[kubectl announcement]: https://kubernetes.io/blog/2019/03/25/kubernetes-1-14-release-announcement
|
||||
[kubectl book]: https://kubectl.docs.kubernetes.io/pages/app_customization/introduction.html
|
||||
[kubernetes documentation]: https://kubernetes.io/docs/tasks/manage-kubernetes-objects/kustomization/
|
||||
[kubernetes style]: docs/glossary.md#kubernetes-style-object
|
||||
[kustomization]: docs/glossary.md#kustomization
|
||||
[overlay]: docs/glossary.md#overlay
|
||||
|
||||
@@ -38,6 +38,7 @@ What transformations (customizations) should be applied?
|
||||
| [namePrefix](#nameprefix) | string | Prepends value to the names of all resources |
|
||||
| [nameSuffix](#namesuffix) | string | The value is appended to the names of all resources. |
|
||||
| [replicas](#replicas) | list | Replicas modifies the number of replicas of a resource. |
|
||||
| [patches](#patches) | list | Each entry should resolve to a patch that can be applied to multiple targets. |
|
||||
|[patchesStrategicMerge](#patchesstrategicmerge)| list |Each entry in this list should resolve to a partial or complete resource definition file.|
|
||||
|[patchesJson6902](#patchesjson6902)| list |Each entry in this list should resolve to a kubernetes object and a JSON patch that will be applied to the object.|
|
||||
|[transformers](#transformers)|list|[plugin](plugins) configuration files|
|
||||
@@ -263,11 +264,47 @@ resource type is ConfigMap or Secret.
|
||||
nameSuffix: -v2
|
||||
```
|
||||
|
||||
### patches
|
||||
|
||||
Each entry in this list should resolve to an Patch object,
|
||||
which includes a patch and a target selector.
|
||||
The patch can be either a strategic merge patch or a JSON patch.
|
||||
it can be either a patch file or an inline string.
|
||||
The target selects
|
||||
resources by group, version, kind, name, namespace,
|
||||
labelSelector and annotationSelector. A resource
|
||||
which matches all the specified fields is selected
|
||||
to apply the patch.
|
||||
|
||||
```
|
||||
patches:
|
||||
- path: patch.yaml
|
||||
target:
|
||||
group: apps
|
||||
version: v1
|
||||
kind: Deployment
|
||||
name: deploy.*
|
||||
labelSelector: "env=dev"
|
||||
annotationSelector: "zone=west"
|
||||
- patch: |-
|
||||
- op: replace
|
||||
path: some/existing/path
|
||||
value: new value
|
||||
target:
|
||||
kind: MyKind
|
||||
labelSelector: "env=dev"
|
||||
```
|
||||
|
||||
The `name` and `namespace` fields of the patch target selector are
|
||||
automatically anchored regular expressions. This means that the value `myapp`
|
||||
is equivalent to `^myapp$`.
|
||||
|
||||
### patchesStrategicMerge
|
||||
|
||||
Each entry in this list should be a relative path
|
||||
Each entry in this list should be either a relative
|
||||
file path or an inline content
|
||||
resolving to a partial or complete resource
|
||||
definition file.
|
||||
definition.
|
||||
|
||||
The names in these (possibly partial) resource
|
||||
files must match names already loaded via the
|
||||
@@ -286,6 +323,22 @@ patchesStrategicMerge:
|
||||
- deployment_increase_memory.yaml
|
||||
```
|
||||
|
||||
The patch content can be a inline string as well.
|
||||
```
|
||||
patchesStrategicMerge:
|
||||
- |-
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: nginx
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nignx:latest
|
||||
```
|
||||
|
||||
### patchesJson6902
|
||||
|
||||
Each entry in this list should resolve to
|
||||
@@ -330,6 +383,23 @@ patchesJson6902:
|
||||
path: add_service_annotation.yaml
|
||||
```
|
||||
|
||||
The patch content can be an inline string as well:
|
||||
|
||||
```
|
||||
patchesJson6902:
|
||||
- target:
|
||||
version: v1
|
||||
kind: Deployment
|
||||
name: my-deployment
|
||||
patch: |-
|
||||
- op: add
|
||||
path: /some/new/path
|
||||
value: value
|
||||
- op: replace
|
||||
path: /some/existing/path
|
||||
value: "new value"
|
||||
```
|
||||
|
||||
### replicas
|
||||
|
||||
Replicas modified the number of replicas for a resource.
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
|
||||
## 发行说明
|
||||
|
||||
* [3.1](../v3.1.0.md) - 2019年7月下旬,扩展 patches 和改进的资源匹配。
|
||||
|
||||
* [3.0](../v3.0.0.md) - 2019年6月下旬,插件开发者发布。
|
||||
|
||||
* [2.1](../v2.1.0.md) - 2019年6月18日
|
||||
|
||||
@@ -26,6 +26,8 @@ go get sigs.k8s.io/kustomize/v3/cmd/kustomize
|
||||
|
||||
* [json patch](jsonpatch.md) -在 kustomization 中应用 json patch 。
|
||||
|
||||
* [patch multiple objects](patchMultipleObjects.md) - 通过一个patch来修改多个资源。
|
||||
|
||||
高级用法
|
||||
|
||||
- generator 插件:
|
||||
@@ -34,6 +36,10 @@ go get sigs.k8s.io/kustomize/v3/cmd/kustomize
|
||||
|
||||
* [secret generation](../secretGeneratorPlugin.md) - 生成 Secret。
|
||||
|
||||
- transformer 插件:
|
||||
|
||||
* [validation transformer](../validationTransformer/README.md) - 通过 transformer 验证资源。
|
||||
|
||||
- 定制内建 transformer 配置
|
||||
|
||||
* [transformer configs](../transformerconfigs/README.md) - 自定义 transformer 配置。
|
||||
|
||||
1
go.sum
1
go.sum
@@ -149,7 +149,6 @@ k8s.io/klog v0.3.3 h1:niceAagH1tzskmaie/icWd7ci1wbG7Bf2c6YGcQv+3c=
|
||||
k8s.io/klog v0.3.3/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
|
||||
k8s.io/kube-openapi v0.0.0-20190603182131-db7b694dc208 h1:5sW+fEHvlJI3Ngolx30CmubFulwH28DhKjGf70Xmtco=
|
||||
k8s.io/kube-openapi v0.0.0-20190603182131-db7b694dc208/go.mod h1:nfDlWeOsu3pUf4yWGL+ERqohP4YsZcBJXWMK+gkzOA4=
|
||||
sigs.k8s.io/kustomize v2.0.3+incompatible h1:JUufWFNlI44MdtnjUqVnvh29rR37PQFzPbLXqhyOyX0=
|
||||
sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=
|
||||
sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs=
|
||||
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
||||
|
||||
@@ -67,6 +67,7 @@ func determineFieldOrder() []string {
|
||||
"GeneratorOptions",
|
||||
"Vars",
|
||||
"Images",
|
||||
"Replicas",
|
||||
"Configurations",
|
||||
"Generators",
|
||||
"Transformers",
|
||||
|
||||
@@ -46,6 +46,7 @@ func TestFieldOrder(t *testing.T) {
|
||||
"GeneratorOptions",
|
||||
"Vars",
|
||||
"Images",
|
||||
"Replicas",
|
||||
"Configurations",
|
||||
"Generators",
|
||||
"Transformers",
|
||||
|
||||
@@ -35,14 +35,14 @@ func ClonerUsingGitExec(repoSpec *RepoSpec) error {
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "no 'git' program on path")
|
||||
}
|
||||
repoSpec.cloneDir, err = fs.NewTmpConfirmedDir()
|
||||
repoSpec.Dir, err = fs.NewTmpConfirmedDir()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cmd := exec.Command(
|
||||
gitProgram,
|
||||
"init",
|
||||
repoSpec.cloneDir.String())
|
||||
repoSpec.Dir.String())
|
||||
var out bytes.Buffer
|
||||
cmd.Stdout = &out
|
||||
err = cmd.Run()
|
||||
@@ -50,7 +50,7 @@ func ClonerUsingGitExec(repoSpec *RepoSpec) error {
|
||||
return errors.Wrapf(
|
||||
err,
|
||||
"trouble initializing empty git repo in %s",
|
||||
repoSpec.cloneDir.String())
|
||||
repoSpec.Dir.String())
|
||||
}
|
||||
|
||||
cmd = exec.Command(
|
||||
@@ -60,7 +60,7 @@ func ClonerUsingGitExec(repoSpec *RepoSpec) error {
|
||||
"origin",
|
||||
repoSpec.CloneSpec())
|
||||
cmd.Stdout = &out
|
||||
cmd.Dir = repoSpec.cloneDir.String()
|
||||
cmd.Dir = repoSpec.Dir.String()
|
||||
err = cmd.Run()
|
||||
if err != nil {
|
||||
return errors.Wrapf(
|
||||
@@ -68,20 +68,20 @@ func ClonerUsingGitExec(repoSpec *RepoSpec) error {
|
||||
"trouble adding remote %s",
|
||||
repoSpec.CloneSpec())
|
||||
}
|
||||
if repoSpec.ref == "" {
|
||||
repoSpec.ref = "master"
|
||||
if repoSpec.Ref == "" {
|
||||
repoSpec.Ref = "master"
|
||||
}
|
||||
cmd = exec.Command(
|
||||
gitProgram,
|
||||
"fetch",
|
||||
"--depth=1",
|
||||
"origin",
|
||||
repoSpec.ref)
|
||||
repoSpec.Ref)
|
||||
cmd.Stdout = &out
|
||||
cmd.Dir = repoSpec.cloneDir.String()
|
||||
cmd.Dir = repoSpec.Dir.String()
|
||||
err = cmd.Run()
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "trouble fetching %s", repoSpec.ref)
|
||||
return errors.Wrapf(err, "trouble fetching %s", repoSpec.Ref)
|
||||
}
|
||||
|
||||
cmd = exec.Command(
|
||||
@@ -90,11 +90,11 @@ func ClonerUsingGitExec(repoSpec *RepoSpec) error {
|
||||
"--hard",
|
||||
"FETCH_HEAD")
|
||||
cmd.Stdout = &out
|
||||
cmd.Dir = repoSpec.cloneDir.String()
|
||||
cmd.Dir = repoSpec.Dir.String()
|
||||
err = cmd.Run()
|
||||
if err != nil {
|
||||
return errors.Wrapf(
|
||||
err, "trouble hard resetting empty repository to %s", repoSpec.ref)
|
||||
err, "trouble hard resetting empty repository to %s", repoSpec.Ref)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -105,7 +105,7 @@ func ClonerUsingGitExec(repoSpec *RepoSpec) error {
|
||||
// used in a test.
|
||||
func DoNothingCloner(dir fs.ConfirmedDir) Cloner {
|
||||
return func(rs *RepoSpec) error {
|
||||
rs.cloneDir = dir
|
||||
rs.Dir = dir
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,36 +39,36 @@ type RepoSpec struct {
|
||||
raw string
|
||||
|
||||
// Host, e.g. github.com
|
||||
host string
|
||||
Host string
|
||||
|
||||
// orgRepo name (organization/repoName),
|
||||
// e.g. kubernetes-sigs/kustomize
|
||||
orgRepo string
|
||||
OrgRepo string
|
||||
|
||||
// ConfirmedDir where the orgRepo is cloned to.
|
||||
cloneDir fs.ConfirmedDir
|
||||
// Dir where the orgRepo is cloned to.
|
||||
Dir fs.ConfirmedDir
|
||||
|
||||
// Relative path in the repository, and in the cloneDir,
|
||||
// to a Kustomization.
|
||||
path string
|
||||
Path string
|
||||
|
||||
// Branch or tag reference.
|
||||
ref string
|
||||
Ref string
|
||||
|
||||
// e.g. .git or empty in case of _git is present
|
||||
gitSuffix string
|
||||
GitSuffix string
|
||||
}
|
||||
|
||||
// CloneSpec returns a string suitable for "git clone {spec}".
|
||||
func (x *RepoSpec) CloneSpec() string {
|
||||
if isAzureHost(x.host) || isAWSHost(x.host) {
|
||||
return x.host + x.orgRepo
|
||||
if isAzureHost(x.Host) || isAWSHost(x.Host) {
|
||||
return x.Host + x.OrgRepo
|
||||
}
|
||||
return x.host + x.orgRepo + x.gitSuffix
|
||||
return x.Host + x.OrgRepo + x.GitSuffix
|
||||
}
|
||||
|
||||
func (x *RepoSpec) CloneDir() fs.ConfirmedDir {
|
||||
return x.cloneDir
|
||||
return x.Dir
|
||||
}
|
||||
|
||||
func (x *RepoSpec) Raw() string {
|
||||
@@ -76,11 +76,11 @@ func (x *RepoSpec) Raw() string {
|
||||
}
|
||||
|
||||
func (x *RepoSpec) AbsPath() string {
|
||||
return x.cloneDir.Join(x.path)
|
||||
return x.Dir.Join(x.Path)
|
||||
}
|
||||
|
||||
func (x *RepoSpec) Cleaner(fSys fs.FileSystem) func() error {
|
||||
return func() error { return fSys.RemoveAll(x.cloneDir.String()) }
|
||||
return func() error { return fSys.RemoveAll(x.Dir.String()) }
|
||||
}
|
||||
|
||||
// From strings like git@github.com:someOrg/someRepo.git or
|
||||
@@ -98,8 +98,8 @@ func NewRepoSpecFromUrl(n string) (*RepoSpec, error) {
|
||||
return nil, fmt.Errorf("url lacks host: %s", n)
|
||||
}
|
||||
return &RepoSpec{
|
||||
raw: n, host: host, orgRepo: orgRepo,
|
||||
cloneDir: notCloned, path: path, ref: gitRef, gitSuffix: gitSuffix}, nil
|
||||
raw: n, Host: host, OrgRepo: orgRepo,
|
||||
Dir: notCloned, Path: path, Ref: gitRef, GitSuffix: gitSuffix}, nil
|
||||
}
|
||||
|
||||
const (
|
||||
|
||||
@@ -72,17 +72,17 @@ func TestNewRepoSpecFromUrl(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Errorf("problem %v", err)
|
||||
}
|
||||
if rs.host != hostSpec {
|
||||
bad = append(bad, []string{"host", uri, rs.host, hostSpec})
|
||||
if rs.Host != hostSpec {
|
||||
bad = append(bad, []string{"host", uri, rs.Host, hostSpec})
|
||||
}
|
||||
if rs.orgRepo != orgRepo {
|
||||
bad = append(bad, []string{"orgRepo", uri, rs.orgRepo, orgRepo})
|
||||
if rs.OrgRepo != orgRepo {
|
||||
bad = append(bad, []string{"orgRepo", uri, rs.OrgRepo, orgRepo})
|
||||
}
|
||||
if rs.path != pathName {
|
||||
bad = append(bad, []string{"path", uri, rs.path, pathName})
|
||||
if rs.Path != pathName {
|
||||
bad = append(bad, []string{"path", uri, rs.Path, pathName})
|
||||
}
|
||||
if rs.ref != hrefArg {
|
||||
bad = append(bad, []string{"ref", uri, rs.ref, hrefArg})
|
||||
if rs.Ref != hrefArg {
|
||||
bad = append(bad, []string{"ref", uri, rs.Ref, hrefArg})
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -201,9 +201,9 @@ func TestNewRepoSpecFromUrl_CloneSpecs(t *testing.T) {
|
||||
t.Errorf("AbsPath expected to be %v, but got %v on %s",
|
||||
testcase.absPath, rs.AbsPath(), testcase.input)
|
||||
}
|
||||
if rs.ref != testcase.ref {
|
||||
if rs.Ref != testcase.ref {
|
||||
t.Errorf("ref expected to be %v, but got %v on %s",
|
||||
testcase.ref, rs.ref, testcase.input)
|
||||
testcase.ref, rs.Ref, testcase.input)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,11 +138,16 @@ func (th *KustTestHarness) ErrorFromLoadAndRunTransformer(
|
||||
|
||||
func (th *KustTestHarness) RunTransformer(
|
||||
config, input string) (resmap.ResMap, error) {
|
||||
transConfig, err := th.rf.RF().FromBytes([]byte(config))
|
||||
resMap, err := th.rf.NewResMapFromBytes([]byte(input))
|
||||
if err != nil {
|
||||
th.t.Fatalf("Err: %v", err)
|
||||
}
|
||||
resMap, err := th.rf.NewResMapFromBytes([]byte(input))
|
||||
return th.RunTransformerFromResMap(config, resMap)
|
||||
}
|
||||
|
||||
func (th *KustTestHarness) RunTransformerFromResMap(
|
||||
config string, resMap resmap.ResMap) (resmap.ResMap, error) {
|
||||
transConfig, err := th.rf.RF().FromBytes([]byte(config))
|
||||
if err != nil {
|
||||
th.t.Fatalf("Err: %v", err)
|
||||
}
|
||||
|
||||
@@ -552,7 +552,7 @@ func (m *resWrangler) makeCopy(copier resCopier) ResMap {
|
||||
// SubsetThatCouldBeReferencedByResource implements ResMap.
|
||||
func (m *resWrangler) SubsetThatCouldBeReferencedByResource(
|
||||
inputRes *resource.Resource) ResMap {
|
||||
result := New()
|
||||
result := newOne()
|
||||
inputId := inputRes.CurId()
|
||||
isInputIdNamespaceable := inputId.IsNamespaceableKind()
|
||||
rctxm := inputRes.PrefixesSuffixesEquals
|
||||
@@ -563,15 +563,16 @@ func (m *resWrangler) SubsetThatCouldBeReferencedByResource(
|
||||
resId := r.CurId()
|
||||
if (!isInputIdNamespaceable || !resId.IsNamespaceableKind() || resId.IsNsEquals(inputId)) &&
|
||||
r.InSameKustomizeCtx(rctxm) {
|
||||
err := result.Append(r)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
result.append(r)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func (m *resWrangler) append(res *resource.Resource) {
|
||||
m.rList = append(m.rList, res)
|
||||
}
|
||||
|
||||
// AppendAll implements ResMap.
|
||||
func (m *resWrangler) AppendAll(other ResMap) error {
|
||||
if other == nil {
|
||||
@@ -650,11 +651,18 @@ func (m *resWrangler) appendReplaceOrMerge(
|
||||
return nil
|
||||
}
|
||||
|
||||
func anchorRegex(pattern string) string {
|
||||
if pattern == "" {
|
||||
return pattern
|
||||
}
|
||||
return "^" + pattern + "$"
|
||||
}
|
||||
|
||||
// Select returns a list of resources that
|
||||
// are selected by a Selector
|
||||
func (m *resWrangler) Select(s types.Selector) ([]*resource.Resource, error) {
|
||||
ns := regexp.MustCompile(s.Namespace)
|
||||
nm := regexp.MustCompile(s.Name)
|
||||
ns := regexp.MustCompile(anchorRegex(s.Namespace))
|
||||
nm := regexp.MustCompile(anchorRegex(s.Name))
|
||||
var result []*resource.Resource
|
||||
for _, r := range m.Resources() {
|
||||
curId := r.CurId()
|
||||
|
||||
@@ -41,6 +41,12 @@ metadata:
|
||||
app: name3
|
||||
annotations:
|
||||
bar: baz
|
||||
---
|
||||
apiVersion: group1/v1
|
||||
kind: Kind2
|
||||
metadata:
|
||||
name: x-name1
|
||||
namespace: x-default
|
||||
`))
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error %v", err)
|
||||
@@ -56,13 +62,13 @@ func TestFindPatchTargets(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
target: types.Selector{
|
||||
Name: "name*",
|
||||
Name: "name.*",
|
||||
},
|
||||
count: 3,
|
||||
},
|
||||
{
|
||||
target: types.Selector{
|
||||
Name: "name*",
|
||||
Name: "name.*",
|
||||
AnnotationSelector: "foo=bar",
|
||||
},
|
||||
count: 2,
|
||||
@@ -78,7 +84,7 @@ func TestFindPatchTargets(t *testing.T) {
|
||||
Gvk: gvk.Gvk{
|
||||
Kind: "Kind1",
|
||||
},
|
||||
Name: "name*",
|
||||
Name: "name.*",
|
||||
},
|
||||
count: 2,
|
||||
},
|
||||
@@ -92,7 +98,7 @@ func TestFindPatchTargets(t *testing.T) {
|
||||
target: types.Selector{
|
||||
Name: "",
|
||||
},
|
||||
count: 3,
|
||||
count: 4,
|
||||
},
|
||||
{
|
||||
target: types.Selector{
|
||||
@@ -104,18 +110,60 @@ func TestFindPatchTargets(t *testing.T) {
|
||||
target: types.Selector{
|
||||
Namespace: "",
|
||||
},
|
||||
count: 3,
|
||||
count: 4,
|
||||
},
|
||||
{
|
||||
target: types.Selector{
|
||||
Namespace: "default",
|
||||
Name: "name*",
|
||||
Name: "name.*",
|
||||
Gvk: gvk.Gvk{
|
||||
Kind: "Kind1",
|
||||
},
|
||||
},
|
||||
count: 1,
|
||||
},
|
||||
{
|
||||
target: types.Selector{
|
||||
Name: "^name.*",
|
||||
},
|
||||
count: 3,
|
||||
},
|
||||
{
|
||||
target: types.Selector{
|
||||
Name: "name.*$",
|
||||
},
|
||||
count: 3,
|
||||
},
|
||||
{
|
||||
target: types.Selector{
|
||||
Name: "^name.*$",
|
||||
},
|
||||
count: 3,
|
||||
},
|
||||
{
|
||||
target: types.Selector{
|
||||
Namespace: "^def.*",
|
||||
},
|
||||
count: 2,
|
||||
},
|
||||
{
|
||||
target: types.Selector{
|
||||
Namespace: "def.*$",
|
||||
},
|
||||
count: 2,
|
||||
},
|
||||
{
|
||||
target: types.Selector{
|
||||
Namespace: "^def.*$",
|
||||
},
|
||||
count: 2,
|
||||
},
|
||||
{
|
||||
target: types.Selector{
|
||||
Namespace: "default",
|
||||
},
|
||||
count: 2,
|
||||
},
|
||||
}
|
||||
for _, testcase := range testcases {
|
||||
actual, err := rm.Select(testcase.target)
|
||||
|
||||
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 {
|
||||
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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -15,7 +15,7 @@ type PatchStrategicMergeTransformerPlugin struct {
|
||||
rf *resmap.Factory
|
||||
loadedPatches []*resource.Resource
|
||||
Paths []types.PatchStrategicMerge `json:"paths,omitempty" yaml:"paths,omitempty"`
|
||||
Patches string `json:patches,omitempty" yaml:"patches,omitempty"`
|
||||
Patches string `json:"patches,omitempty" yaml:"patches,omitempty"`
|
||||
}
|
||||
|
||||
//noinspection GoUnusedGlobalVariable
|
||||
@@ -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))
|
||||
|
||||
@@ -34,8 +34,15 @@ func (p *ReplicaCountTransformerPlugin) Config(
|
||||
}
|
||||
|
||||
func (p *ReplicaCountTransformerPlugin) Transform(m resmap.ResMap) error {
|
||||
|
||||
found := false
|
||||
for i, replicaSpec := range p.FieldSpecs {
|
||||
for _, res := range m.GetMatchingResourcesByOriginalId(p.createMatcher(i)) {
|
||||
matcher := p.createMatcher(i)
|
||||
matchOriginal := m.GetMatchingResourcesByOriginalId(matcher)
|
||||
matchCurrent := m.GetMatchingResourcesByCurrentId(matcher)
|
||||
|
||||
for _, res := range append(matchOriginal, matchCurrent...) {
|
||||
found = true
|
||||
err := transformers.MutateField(
|
||||
res.Map(), replicaSpec.PathSlice(),
|
||||
replicaSpec.CreateIfNotPresent, p.addReplicas)
|
||||
@@ -45,6 +52,15 @@ func (p *ReplicaCountTransformerPlugin) Transform(m resmap.ResMap) error {
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
gvks := make([]string, len(p.FieldSpecs))
|
||||
for i, replicaSpec := range p.FieldSpecs {
|
||||
gvks[i] = replicaSpec.Gvk.String()
|
||||
}
|
||||
return fmt.Errorf("Resource with name %s does not match a config with the following GVK %v",
|
||||
p.Replica.Name, gvks)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -250,7 +250,7 @@ spec:
|
||||
`)
|
||||
}
|
||||
|
||||
func TestPatchJson6902TransformerWithInline(t *testing.T) {
|
||||
func TestPatchJson6902TransformerWithInlineJSON(t *testing.T) {
|
||||
tc := plugins_test.NewEnvForTest(t).Set()
|
||||
defer tc.Reset()
|
||||
|
||||
@@ -290,3 +290,47 @@ spec:
|
||||
dnsPolicy: ClusterFirst
|
||||
`)
|
||||
}
|
||||
|
||||
func TestPatchJson6902TransformerWithInlineYAML(t *testing.T) {
|
||||
tc := plugins_test.NewEnvForTest(t).Set()
|
||||
defer tc.Reset()
|
||||
|
||||
tc.BuildGoPlugin(
|
||||
"builtin", "", "PatchJson6902Transformer")
|
||||
|
||||
th := kusttest_test.NewKustTestPluginHarness(t, "/app")
|
||||
|
||||
rm := th.LoadAndRunTransformer(`
|
||||
apiVersion: builtin
|
||||
kind: PatchJson6902Transformer
|
||||
metadata:
|
||||
name: notImportantHere
|
||||
target:
|
||||
group: apps
|
||||
version: v1
|
||||
kind: Deployment
|
||||
name: myDeploy
|
||||
jsonOp: |-
|
||||
- op: add
|
||||
path: /spec/template/spec/dnsPolicy
|
||||
value: ClusterFirst
|
||||
`, target)
|
||||
|
||||
th.AssertActualEqualsExpected(rm, `
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: myDeploy
|
||||
spec:
|
||||
replica: 2
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
old-label: old-value
|
||||
spec:
|
||||
containers:
|
||||
- image: nginx
|
||||
name: nginx
|
||||
dnsPolicy: ClusterFirst
|
||||
`)
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ type plugin struct {
|
||||
rf *resmap.Factory
|
||||
loadedPatches []*resource.Resource
|
||||
Paths []types.PatchStrategicMerge `json:"paths,omitempty" yaml:"paths,omitempty"`
|
||||
Patches string `json:patches,omitempty" yaml:"patches,omitempty"`
|
||||
Patches string `json:"patches,omitempty" yaml:"patches,omitempty"`
|
||||
}
|
||||
|
||||
//noinspection GoUnusedGlobalVariable
|
||||
@@ -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))
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -181,7 +183,7 @@ spec:
|
||||
`)
|
||||
}
|
||||
|
||||
func TestPatchStrategicMergeTransformerWithInline(t *testing.T) {
|
||||
func TestPatchStrategicMergeTransformerWithInlineJSON(t *testing.T) {
|
||||
tc := plugins_test.NewEnvForTest(t).Set()
|
||||
defer tc.Reset()
|
||||
|
||||
@@ -216,6 +218,58 @@ spec:
|
||||
`)
|
||||
}
|
||||
|
||||
func TestPatchStrategicMergeTransformerWithInlineYAML(t *testing.T) {
|
||||
tc := plugins_test.NewEnvForTest(t).Set()
|
||||
defer tc.Reset()
|
||||
|
||||
tc.BuildGoPlugin(
|
||||
"builtin", "", "PatchStrategicMergeTransformer")
|
||||
|
||||
th := kusttest_test.NewKustTestPluginHarness(t, "/app")
|
||||
|
||||
rm := th.LoadAndRunTransformer(`
|
||||
apiVersion: builtin
|
||||
kind: PatchStrategicMergeTransformer
|
||||
metadata:
|
||||
name: notImportantHere
|
||||
patches: |-
|
||||
apiVersion: apps/v1
|
||||
metadata:
|
||||
name: myDeploy
|
||||
kind: Deployment
|
||||
spec:
|
||||
replica: 3
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
metadata:
|
||||
name: myDeploy
|
||||
kind: Deployment
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx:latest
|
||||
`, target)
|
||||
|
||||
th.AssertActualEqualsExpected(rm, `
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: myDeploy
|
||||
spec:
|
||||
replica: 3
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
old-label: old-value
|
||||
spec:
|
||||
containers:
|
||||
- image: nginx:latest
|
||||
name: nginx
|
||||
`)
|
||||
}
|
||||
|
||||
func TestPatchStrategicMergeTransformerMultiplePatches(t *testing.T) {
|
||||
tc := plugins_test.NewEnvForTest(t).Set()
|
||||
defer tc.Reset()
|
||||
@@ -1226,4 +1280,4 @@ paths:
|
||||
`, target)
|
||||
|
||||
th.AssertActualEqualsExpected(rm, ``)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,8 +35,15 @@ func (p *plugin) Config(
|
||||
}
|
||||
|
||||
func (p *plugin) Transform(m resmap.ResMap) error {
|
||||
|
||||
found := false
|
||||
for i, replicaSpec := range p.FieldSpecs {
|
||||
for _, res := range m.GetMatchingResourcesByOriginalId(p.createMatcher(i)) {
|
||||
matcher := p.createMatcher(i)
|
||||
matchOriginal := m.GetMatchingResourcesByOriginalId(matcher)
|
||||
matchCurrent := m.GetMatchingResourcesByCurrentId(matcher)
|
||||
|
||||
for _, res := range append(matchOriginal, matchCurrent...) {
|
||||
found = true
|
||||
err := transformers.MutateField(
|
||||
res.Map(), replicaSpec.PathSlice(),
|
||||
replicaSpec.CreateIfNotPresent, p.addReplicas)
|
||||
@@ -46,6 +53,15 @@ func (p *plugin) Transform(m resmap.ResMap) error {
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
gvks := make([]string, len(p.FieldSpecs))
|
||||
for i, replicaSpec := range p.FieldSpecs {
|
||||
gvks[i] = replicaSpec.Gvk.String()
|
||||
}
|
||||
return fmt.Errorf("Resource with name %s does not match a config with the following GVK %v",
|
||||
p.Replica.Name, gvks)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -151,3 +151,85 @@ spec:
|
||||
app: app
|
||||
`)
|
||||
}
|
||||
|
||||
func TestMatchesCurrentID(t *testing.T) {
|
||||
tc := plugins_test.NewEnvForTest(t).Set()
|
||||
defer tc.Reset()
|
||||
|
||||
tc.BuildGoPlugin("builtin", "", "PrefixSuffixTransformer")
|
||||
tc.BuildGoPlugin("builtin", "", "ReplicaCountTransformer")
|
||||
|
||||
th := kusttest_test.NewKustTestPluginHarness(t, "/app")
|
||||
|
||||
rm := th.LoadAndRunTransformer(`
|
||||
apiVersion: builtin
|
||||
kind: PrefixSuffixTransformer
|
||||
metadata:
|
||||
name: notImportantHere
|
||||
suffix: -test
|
||||
fieldSpecs:
|
||||
- path: metadata/name
|
||||
`, `
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: deployment`)
|
||||
|
||||
rm, _ = th.RunTransformerFromResMap(`
|
||||
apiVersion: builtin
|
||||
kind: ReplicaCountTransformer
|
||||
metadata:
|
||||
name: notImportantHere
|
||||
|
||||
replica:
|
||||
name: deployment-test
|
||||
count: 23
|
||||
fieldSpecs:
|
||||
- path: spec/replicas
|
||||
create: true
|
||||
kind: Deployment`, rm)
|
||||
th.AssertActualEqualsExpected(rm, `
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: deployment-test
|
||||
spec:
|
||||
replicas: 23
|
||||
`)
|
||||
}
|
||||
|
||||
func TestNoMatch(t *testing.T) {
|
||||
tc := plugins_test.NewEnvForTest(t).Set()
|
||||
defer tc.Reset()
|
||||
|
||||
tc.BuildGoPlugin("builtin", "", "ReplicaCountTransformer")
|
||||
|
||||
th := kusttest_test.NewKustTestPluginHarness(t, "/app")
|
||||
|
||||
err := th.ErrorFromLoadAndRunTransformer(`
|
||||
apiVersion: builtin
|
||||
kind: ReplicaCountTransformer
|
||||
metadata:
|
||||
name: notImportantHere
|
||||
replica:
|
||||
name: service
|
||||
count: 3
|
||||
fieldSpecs:
|
||||
- path: spec/replicas
|
||||
create: true
|
||||
kind: Deployment
|
||||
`, `
|
||||
kind: Service
|
||||
metadata:
|
||||
name: service
|
||||
spec:
|
||||
`)
|
||||
|
||||
if err == nil {
|
||||
t.Fatalf("No match should return an error")
|
||||
}
|
||||
if err.Error() !=
|
||||
"Resource with name service does not match a config with the following GVK [~G_~V_Deployment]" {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user