mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-07-01 02:11:20 +00:00
Compare commits
195 Commits
cmd/config
...
release-ap
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6c8db65a90 | ||
|
|
35b5b7554f | ||
|
|
6395344bcb | ||
|
|
4a3bb926c5 | ||
|
|
ba5335cf48 | ||
|
|
03ac2e1ada | ||
|
|
1cf5b00af8 | ||
|
|
9097f7b5a6 | ||
|
|
0c8174544f | ||
|
|
a37572d193 | ||
|
|
ba7315ca76 | ||
|
|
ddf768195c | ||
|
|
b11cc3ae67 | ||
|
|
22668eae16 | ||
|
|
02eb788b78 | ||
|
|
41fb6915b3 | ||
|
|
596519d3f2 | ||
|
|
d3d92157fa | ||
|
|
c83ebd9530 | ||
|
|
c3b5d8fa19 | ||
|
|
7a773a3a48 | ||
|
|
46d4934b68 | ||
|
|
d0ef2f70a1 | ||
|
|
b8d2ff2afa | ||
|
|
7e0158e1e9 | ||
|
|
5948f6aa63 | ||
|
|
496a962a53 | ||
|
|
17b42a99f5 | ||
|
|
271f393218 | ||
|
|
c0dc68d6e7 | ||
|
|
188e35fbfd | ||
|
|
233b6adf7e | ||
|
|
41296b9814 | ||
|
|
66e4e1582b | ||
|
|
2e230b4d4b | ||
|
|
bcae65770a | ||
|
|
d49e5aa5aa | ||
|
|
94af647556 | ||
|
|
9d5491c2e2 | ||
|
|
cf89eae804 | ||
|
|
9452a031ba | ||
|
|
a464ed0c59 | ||
|
|
ec212711d4 | ||
|
|
2f2e14e953 | ||
|
|
ed72bb02d4 | ||
|
|
02e0b38bb0 | ||
|
|
01ab069bd2 | ||
|
|
cdc4a5083b | ||
|
|
5e84de2a89 | ||
|
|
e5041bae6f | ||
|
|
0d600af35a | ||
|
|
0989b26098 | ||
|
|
7888aef305 | ||
|
|
fe604fd3d1 | ||
|
|
4fc02497ae | ||
|
|
e96c38e3ab | ||
|
|
29104d6fa9 | ||
|
|
df57e196d8 | ||
|
|
f3c825f550 | ||
|
|
03c94eabb7 | ||
|
|
c071cdaedd | ||
|
|
f68a0c50d9 | ||
|
|
db34e923c5 | ||
|
|
df80b29694 | ||
|
|
ea193328e3 | ||
|
|
2d4bce5112 | ||
|
|
af06ae6b69 | ||
|
|
46875b6ac4 | ||
|
|
0fa010c7e7 | ||
|
|
3e652d6fea | ||
|
|
f54014ce3b | ||
|
|
08924dc2f5 | ||
|
|
49c0ed1326 | ||
|
|
7440f974b8 | ||
|
|
ab9b89213b | ||
|
|
9fc012cc4e | ||
|
|
877d72b10b | ||
|
|
c743f13d0d | ||
|
|
0d32543ebd | ||
|
|
28ee975948 | ||
|
|
2a9adbeb1e | ||
|
|
672c751715 | ||
|
|
d3a7b9008b | ||
|
|
b0d2e4bdcd | ||
|
|
71bf0d5d14 | ||
|
|
0a9c5cb0cf | ||
|
|
ff4136b1a2 | ||
|
|
1567b96ed3 | ||
|
|
14947e449b | ||
|
|
b368b347d1 | ||
|
|
5c359bda28 | ||
|
|
c94b5d8f25 | ||
|
|
b699204a9e | ||
|
|
cf3a452ddd | ||
|
|
faad014f96 | ||
|
|
8e46ef57be | ||
|
|
458d48430a | ||
|
|
3cecdc6214 | ||
|
|
7cac778866 | ||
|
|
0aa379c228 | ||
|
|
cd0f9b0c5b | ||
|
|
651f0c1097 | ||
|
|
6348ea9515 | ||
|
|
4b64f1e0e8 | ||
|
|
7306402cca | ||
|
|
485f7d44d9 | ||
|
|
9e57ab72fc | ||
|
|
d17ef91d94 | ||
|
|
e97cecf9dc | ||
|
|
5833f4ca80 | ||
|
|
e86c479690 | ||
|
|
d082c75b65 | ||
|
|
d2e59002ae | ||
|
|
c857ff8371 | ||
|
|
866e84059f | ||
|
|
497d2ee031 | ||
|
|
c4febc59d5 | ||
|
|
19955e73ff | ||
|
|
271bf31ce9 | ||
|
|
809182c6b6 | ||
|
|
0dd3d84104 | ||
|
|
de6b978491 | ||
|
|
8fa8e14eeb | ||
|
|
26b5e628cf | ||
|
|
80853c61b8 | ||
|
|
c5ff592810 | ||
|
|
b9df5686f4 | ||
|
|
7ff87ef5b9 | ||
|
|
c4d38108cf | ||
|
|
784ae5efa3 | ||
|
|
e8640724a9 | ||
|
|
7b0ec99d90 | ||
|
|
fbfcb0479a | ||
|
|
3421fcf81e | ||
|
|
97de780feb | ||
|
|
3490fb8716 | ||
|
|
2fe04496c2 | ||
|
|
b0d7721049 | ||
|
|
18f22f10a3 | ||
|
|
3ae5aa9e13 | ||
|
|
48f21e920a | ||
|
|
dcdefca70e | ||
|
|
c64351aa01 | ||
|
|
c60979ee3e | ||
|
|
cb80659c22 | ||
|
|
b1086ac49b | ||
|
|
1fcd66258f | ||
|
|
d1d578c392 | ||
|
|
f67dd5bbbd | ||
|
|
ac5c51ba2c | ||
|
|
53cc76fe43 | ||
|
|
07eb595eb2 | ||
|
|
8cb7acfdcb | ||
|
|
975482390f | ||
|
|
701695c343 | ||
|
|
8db1267983 | ||
|
|
da7ec577b2 | ||
|
|
d17b171207 | ||
|
|
70ce89d993 | ||
|
|
e25db3df2e | ||
|
|
3eae520532 | ||
|
|
3ec7b10bc0 | ||
|
|
6dabba1d23 | ||
|
|
bd05631887 | ||
|
|
6950a0d246 | ||
|
|
c90504a19d | ||
|
|
8dab94964f | ||
|
|
ff40460d3b | ||
|
|
a7f4db7fb4 | ||
|
|
5d0762411c | ||
|
|
b4e116346e | ||
|
|
9091919699 | ||
|
|
702a56e2f1 | ||
|
|
00a9c59dd7 | ||
|
|
4dfc2a9507 | ||
|
|
2f17803c0a | ||
|
|
5ed96a34d7 | ||
|
|
14cb815b5d | ||
|
|
a5df6f7fd9 | ||
|
|
4f5dfb5d42 | ||
|
|
6374d3d593 | ||
|
|
22f9daa3ab | ||
|
|
c3c7013f09 | ||
|
|
3277ff9dbf | ||
|
|
746bd18a8c | ||
|
|
d7763045ea | ||
|
|
30612cfd17 | ||
|
|
3006846d67 | ||
|
|
2f9617ff56 | ||
|
|
6a7caf4192 | ||
|
|
b79d77a8a7 | ||
|
|
91f65b3441 | ||
|
|
26b9af0379 | ||
|
|
54ae9ba9fc | ||
|
|
b73dfe7f35 |
2
.github/ISSUE_TEMPLATE/bug_report.md
vendored
2
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -8,7 +8,7 @@ assignees: ""
|
|||||||
---
|
---
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
Please read this page: https://kubernetes-sigs.github.io/kustomize/contributing/bugs/ before
|
Please read this page: https://kubectl.docs.kubernetes.io/contributing/kustomize/bugs/ before
|
||||||
filing a bug
|
filing a bug
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
|||||||
6
.github/dependabot.yml
vendored
Normal file
6
.github/dependabot.yml
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
version: 2
|
||||||
|
updates:
|
||||||
|
- package-ecosystem: "github-actions"
|
||||||
|
directory: "/"
|
||||||
|
schedule:
|
||||||
|
interval: "weekly"
|
||||||
59
.github/workflows/go.yml
vendored
59
.github/workflows/go.yml
vendored
@@ -6,6 +6,9 @@ on:
|
|||||||
pull_request:
|
pull_request:
|
||||||
branches: [ master ]
|
branches: [ master ]
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
|
||||||
lint:
|
lint:
|
||||||
@@ -14,18 +17,21 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
|
|
||||||
- name: Set up Go 1.x
|
- name: Set up Go 1.x
|
||||||
uses: actions/setup-go@v2
|
uses: actions/setup-go@v3
|
||||||
with:
|
with:
|
||||||
go-version: ^1.16
|
go-version: ^1.16
|
||||||
id: go
|
id: go
|
||||||
|
|
||||||
- name: Check out code into the Go module directory
|
- name: Check out code into the Go module directory
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Lint
|
- name: Lint
|
||||||
run: ./hack/kyaml-pre-commit.sh
|
run: make lint
|
||||||
env:
|
|
||||||
KUSTOMIZE_DOCKER_E2E: false # don't need to do e2e tests for linting
|
- name: Verify boilerplate
|
||||||
|
run: make check-license
|
||||||
|
|
||||||
test-linux:
|
test-linux:
|
||||||
name: Test Linux
|
name: Test Linux
|
||||||
@@ -33,7 +39,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
|
|
||||||
- name: Set up Go 1.x
|
- name: Set up Go 1.x
|
||||||
uses: actions/setup-go@v2
|
uses: actions/setup-go@v3
|
||||||
with:
|
with:
|
||||||
go-version: ^1.16
|
go-version: ^1.16
|
||||||
id: go
|
id: go
|
||||||
@@ -41,17 +47,8 @@ jobs:
|
|||||||
- name: Check out code into the Go module directory
|
- name: Check out code into the Go module directory
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
- name: Test kyaml
|
- name: Test all modules
|
||||||
run: go test -cover ./...
|
run: make test-unit-non-plugin
|
||||||
working-directory: ./kyaml
|
|
||||||
|
|
||||||
- name: Test api
|
|
||||||
run: go test -cover ./... -ldflags "-X sigs.k8s.io/kustomize/api/provenance.version=v444.333.222"
|
|
||||||
working-directory: ./api
|
|
||||||
|
|
||||||
- name: Test cmd/config
|
|
||||||
run: go test -cover ./...
|
|
||||||
working-directory: ./cmd/config
|
|
||||||
env:
|
env:
|
||||||
KUSTOMIZE_DOCKER_E2E: true
|
KUSTOMIZE_DOCKER_E2E: true
|
||||||
|
|
||||||
@@ -61,7 +58,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
|
|
||||||
- name: Set up Go 1.x
|
- name: Set up Go 1.x
|
||||||
uses: actions/setup-go@v2
|
uses: actions/setup-go@v3
|
||||||
with:
|
with:
|
||||||
go-version: ^1.16
|
go-version: ^1.16
|
||||||
id: go
|
id: go
|
||||||
@@ -69,17 +66,8 @@ jobs:
|
|||||||
- name: Check out code into the Go module directory
|
- name: Check out code into the Go module directory
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
- name: Test kyaml
|
- name: Test all modules
|
||||||
run: go test -cover ./...
|
run: make test-unit-non-plugin
|
||||||
working-directory: ./kyaml
|
|
||||||
|
|
||||||
- name: Test api
|
|
||||||
run: go test -cover ./... -ldflags "-X sigs.k8s.io/kustomize/api/provenance.version=v444.333.222"
|
|
||||||
working-directory: ./api
|
|
||||||
|
|
||||||
- name: Test cmd/config
|
|
||||||
run: go test -cover ./...
|
|
||||||
working-directory: ./cmd/config
|
|
||||||
env:
|
env:
|
||||||
KUSTOMIZE_DOCKER_E2E: false # docker not installed on mac
|
KUSTOMIZE_DOCKER_E2E: false # docker not installed on mac
|
||||||
|
|
||||||
@@ -89,7 +77,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
|
|
||||||
- name: Set up Go 1.x
|
- name: Set up Go 1.x
|
||||||
uses: actions/setup-go@v2
|
uses: actions/setup-go@v3
|
||||||
with:
|
with:
|
||||||
go-version: ^1.16
|
go-version: ^1.16
|
||||||
id: go
|
id: go
|
||||||
@@ -101,13 +89,14 @@ jobs:
|
|||||||
run: go test -cover ./...
|
run: go test -cover ./...
|
||||||
working-directory: ./kyaml
|
working-directory: ./kyaml
|
||||||
|
|
||||||
# TODO: uncomment once Windows tests are passing.
|
|
||||||
# - name: Test api
|
|
||||||
# run: go test -cover ./... -ldflags "-X sigs.k8s.io/kustomize/api/provenance.version=v444.333.222"
|
|
||||||
# working-directory: ./api
|
|
||||||
|
|
||||||
- name: Test cmd/config
|
- name: Test cmd/config
|
||||||
run: go test -cover ./...
|
run: go test -cover ./...
|
||||||
working-directory: ./cmd/config
|
working-directory: ./cmd/config
|
||||||
env:
|
env:
|
||||||
KUSTOMIZE_DOCKER_E2E: false # docker on windows not working well yet
|
KUSTOMIZE_DOCKER_E2E: false # docker on windows not working well yet
|
||||||
|
|
||||||
|
# TODO (#4001): replace specific modules above with this once Windows tests are passing.
|
||||||
|
#- name: Test all modules
|
||||||
|
# run: make test-unit-non-plugin
|
||||||
|
# env:
|
||||||
|
# KUSTOMIZE_DOCKER_E2E: false # docker on windows not working well yet
|
||||||
|
|||||||
10
.gitignore
vendored
10
.gitignore
vendored
@@ -21,3 +21,13 @@
|
|||||||
*.DS_store
|
*.DS_store
|
||||||
|
|
||||||
.bin
|
.bin
|
||||||
|
|
||||||
|
# Hugo site
|
||||||
|
publishedSite/
|
||||||
|
site/public/
|
||||||
|
site/resources/
|
||||||
|
site/.hugo_build.lock
|
||||||
|
**/node_modules/
|
||||||
|
|
||||||
|
# goreleaser artifacts
|
||||||
|
**/dist/
|
||||||
|
|||||||
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
[submodule "site/themes/docsy"]
|
||||||
|
path = site/themes/docsy
|
||||||
|
url = https://github.com/google/docsy.git
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
run:
|
|
||||||
deadline: 5m
|
|
||||||
|
|
||||||
linters:
|
|
||||||
disable-all: true
|
|
||||||
enable:
|
|
||||||
- bodyclose
|
|
||||||
- deadcode
|
|
||||||
- depguard
|
|
||||||
# - dogsled
|
|
||||||
- dupl
|
|
||||||
# - errcheck
|
|
||||||
# - funlen
|
|
||||||
# - gochecknoinits
|
|
||||||
- goconst
|
|
||||||
# - gocritic
|
|
||||||
- gocyclo
|
|
||||||
- gofmt
|
|
||||||
- goimports
|
|
||||||
- golint
|
|
||||||
- gosec
|
|
||||||
- gosimple
|
|
||||||
- govet
|
|
||||||
- ineffassign
|
|
||||||
- interfacer
|
|
||||||
- lll
|
|
||||||
- misspell
|
|
||||||
- nakedret
|
|
||||||
# - scopelint
|
|
||||||
- staticcheck
|
|
||||||
- structcheck
|
|
||||||
# stylecheck demands that acronyms not be treated as words
|
|
||||||
# in camelCase, so JsonOp become JSONOp, etc. Yuck.
|
|
||||||
# - stylecheck
|
|
||||||
- typecheck
|
|
||||||
- unconvert
|
|
||||||
- unparam
|
|
||||||
- unused
|
|
||||||
- varcheck
|
|
||||||
# - whitespace
|
|
||||||
|
|
||||||
linters-settings:
|
|
||||||
dupl:
|
|
||||||
threshold: 400
|
|
||||||
lll:
|
|
||||||
line-length: 170
|
|
||||||
gocyclo:
|
|
||||||
min-complexity: 15
|
|
||||||
golint:
|
|
||||||
min-confidence: 0.85
|
|
||||||
136
.golangci.yml
Normal file
136
.golangci.yml
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
# Copyright 2019 The Kubernetes Authors.
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
run:
|
||||||
|
deadline: 5m
|
||||||
|
|
||||||
|
linters:
|
||||||
|
# please, do not use `enable-all`: it's deprecated and will be removed soon.
|
||||||
|
# inverted configuration with `enable-all` and `disable` is not scalable during updates of golangci-lint
|
||||||
|
disable-all: true
|
||||||
|
enable:
|
||||||
|
- asciicheck
|
||||||
|
- bidichk
|
||||||
|
- bodyclose
|
||||||
|
- contextcheck
|
||||||
|
# - cyclop
|
||||||
|
- deadcode
|
||||||
|
- depguard
|
||||||
|
- dogsled
|
||||||
|
- dupl
|
||||||
|
- durationcheck
|
||||||
|
- errcheck
|
||||||
|
- errname
|
||||||
|
- errorlint
|
||||||
|
- exhaustive
|
||||||
|
# - exhaustivestruct
|
||||||
|
- exportloopref
|
||||||
|
# - forbidigo
|
||||||
|
- forcetypeassert
|
||||||
|
# - funlen
|
||||||
|
# - gci
|
||||||
|
- gochecknoglobals
|
||||||
|
- gochecknoinits
|
||||||
|
# - gocognit
|
||||||
|
- goconst
|
||||||
|
- gocritic
|
||||||
|
- gocyclo
|
||||||
|
# - godot
|
||||||
|
# - godox
|
||||||
|
- goerr113
|
||||||
|
- gofmt
|
||||||
|
# - gofumpt
|
||||||
|
- goheader
|
||||||
|
- goimports
|
||||||
|
- gomnd
|
||||||
|
- gomoddirectives
|
||||||
|
- gomodguard
|
||||||
|
- goprintffuncname
|
||||||
|
- gosec
|
||||||
|
- gosimple
|
||||||
|
- govet
|
||||||
|
# - ifshort # too many false positives
|
||||||
|
- importas
|
||||||
|
- ineffassign
|
||||||
|
# - ireturn
|
||||||
|
- lll
|
||||||
|
- makezero
|
||||||
|
- misspell
|
||||||
|
- nakedret
|
||||||
|
- nestif
|
||||||
|
- nilerr
|
||||||
|
# - nilnil
|
||||||
|
# - nlreturn
|
||||||
|
# - noctx
|
||||||
|
- nolintlint
|
||||||
|
# - paralleltest
|
||||||
|
- prealloc
|
||||||
|
- predeclared
|
||||||
|
- promlinter
|
||||||
|
- revive
|
||||||
|
- rowserrcheck
|
||||||
|
- sqlclosecheck
|
||||||
|
- staticcheck
|
||||||
|
- structcheck
|
||||||
|
# - stylecheck
|
||||||
|
- tagliatelle
|
||||||
|
- tenv
|
||||||
|
- testpackage
|
||||||
|
- thelper
|
||||||
|
- tparallel
|
||||||
|
- typecheck
|
||||||
|
- unconvert
|
||||||
|
- unparam
|
||||||
|
- unused
|
||||||
|
- varcheck
|
||||||
|
# - varnamelen
|
||||||
|
- wastedassign
|
||||||
|
- whitespace
|
||||||
|
- wrapcheck
|
||||||
|
# - wsl
|
||||||
|
|
||||||
|
linters-settings:
|
||||||
|
dupl:
|
||||||
|
threshold: 400
|
||||||
|
lll:
|
||||||
|
line-length: 170
|
||||||
|
gocyclo:
|
||||||
|
min-complexity: 30
|
||||||
|
revive:
|
||||||
|
rules:
|
||||||
|
- name: var-naming
|
||||||
|
arguments:
|
||||||
|
- [ "ID", "API", "JSON" ] # AllowList
|
||||||
|
- [ ] # DenyList
|
||||||
|
gomoddirectives:
|
||||||
|
replace-local: true
|
||||||
|
gosec:
|
||||||
|
config:
|
||||||
|
G306: "0644"
|
||||||
|
gomnd:
|
||||||
|
ignored-functions:
|
||||||
|
- ioutil.WriteFile
|
||||||
|
wrapcheck:
|
||||||
|
ignoreSigs:
|
||||||
|
# defaults
|
||||||
|
- .Errorf(
|
||||||
|
- errors.New(
|
||||||
|
- errors.Unwrap(
|
||||||
|
- .Wrap(
|
||||||
|
- .Wrapf(
|
||||||
|
- .WithMessage(
|
||||||
|
- .WithMessagef(
|
||||||
|
- .WithStack(
|
||||||
|
# from kyaml's errors package
|
||||||
|
- .WrapPrefixf(
|
||||||
|
|
||||||
|
issues:
|
||||||
|
new-from-rev: c94b5d8f2 # enables us to enforce a larger set of linters for new code than pass on existing code
|
||||||
|
max-same-issues: 0
|
||||||
|
exclude-rules:
|
||||||
|
- linters:
|
||||||
|
- revive
|
||||||
|
text: "don't use leading"
|
||||||
|
- linters:
|
||||||
|
- staticcheck
|
||||||
|
text: "SA1019: kioutil.Legacy"
|
||||||
349
Makefile
349
Makefile
@@ -3,6 +3,8 @@
|
|||||||
#
|
#
|
||||||
# Makefile for kustomize CLI and API.
|
# Makefile for kustomize CLI and API.
|
||||||
|
|
||||||
|
LATEST_V4_RELEASE=v4.5.4
|
||||||
|
|
||||||
SHELL := /usr/bin/env bash
|
SHELL := /usr/bin/env bash
|
||||||
GOOS = $(shell go env GOOS)
|
GOOS = $(shell go env GOOS)
|
||||||
GOARCH = $(shell go env GOARCH)
|
GOARCH = $(shell go env GOARCH)
|
||||||
@@ -11,8 +13,6 @@ ifeq ($(MYGOBIN),)
|
|||||||
MYGOBIN = $(shell go env GOPATH)/bin
|
MYGOBIN = $(shell go env GOPATH)/bin
|
||||||
endif
|
endif
|
||||||
export PATH := $(MYGOBIN):$(PATH)
|
export PATH := $(MYGOBIN):$(PATH)
|
||||||
MODULES := '"cmd/config" "api/" "kustomize/" "kyaml/"'
|
|
||||||
LATEST_V4_RELEASE=v4.3.0
|
|
||||||
|
|
||||||
# Provide defaults for REPO_OWNER and REPO_NAME if not present.
|
# Provide defaults for REPO_OWNER and REPO_NAME if not present.
|
||||||
# Typically these values would be provided by Prow.
|
# Typically these values would be provided by Prow.
|
||||||
@@ -24,48 +24,35 @@ ifndef REPO_NAME
|
|||||||
REPO_NAME := "kustomize"
|
REPO_NAME := "kustomize"
|
||||||
endif
|
endif
|
||||||
|
|
||||||
.PHONY: all
|
|
||||||
all: install-tools verify-kustomize
|
|
||||||
|
|
||||||
.PHONY: verify-kustomize
|
# --- Plugins ---
|
||||||
verify-kustomize: \
|
include Makefile-plugins.mk
|
||||||
lint-kustomize \
|
|
||||||
test-unit-kustomize-all \
|
|
||||||
test-examples-kustomize-against-HEAD \
|
|
||||||
test-examples-kustomize-against-v4-release
|
|
||||||
|
|
||||||
# The following target referenced by a file in
|
|
||||||
# https://github.com/kubernetes/test-infra/tree/master/config/jobs/kubernetes-sigs/kustomize
|
|
||||||
.PHONY: prow-presubmit-check
|
|
||||||
prow-presubmit-check: \
|
|
||||||
install-tools \
|
|
||||||
lint-kustomize \
|
|
||||||
test-unit-kustomize-all \
|
|
||||||
test-unit-cmd-all \
|
|
||||||
test-go-mod \
|
|
||||||
test-examples-kustomize-against-HEAD \
|
|
||||||
test-examples-kustomize-against-v4-release
|
|
||||||
|
|
||||||
.PHONY: verify-kustomize-e2e
|
# --- Tool management ---
|
||||||
verify-kustomize-e2e: test-examples-e2e-kustomize
|
include Makefile-tools.mk
|
||||||
|
|
||||||
# Other builds in this repo might want a different linter version.
|
.PHONY: install-tools
|
||||||
# Without one Makefile to rule them all, the different makes
|
install-tools: \
|
||||||
# cannot assume that golanci-lint is at the version they want.
|
install-local-tools \
|
||||||
# This installs what kustomize wants to use.
|
install-out-of-tree-tools
|
||||||
$(MYGOBIN)/golangci-lint-kustomize:
|
|
||||||
rm -f $(CURDIR)/hack/golangci-lint
|
|
||||||
GOBIN=$(CURDIR)/hack go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.23.8
|
|
||||||
mv $(CURDIR)/hack/golangci-lint $(MYGOBIN)/golangci-lint-kustomize
|
|
||||||
|
|
||||||
$(MYGOBIN)/mdrip:
|
.PHONY: uninstall-tools
|
||||||
go install github.com/monopole/mdrip@v1.0.2
|
uninstall-tools: \
|
||||||
|
uninstall-local-tools \
|
||||||
|
uninstall-out-of-tree-tools
|
||||||
|
|
||||||
$(MYGOBIN)/stringer:
|
.PHONY: install-local-tools
|
||||||
go get golang.org/x/tools/cmd/stringer
|
install-local-tools: \
|
||||||
|
$(MYGOBIN)/gorepomod \
|
||||||
|
$(MYGOBIN)/k8scopy \
|
||||||
|
$(MYGOBIN)/pluginator
|
||||||
|
|
||||||
$(MYGOBIN)/goimports:
|
.PHONY: uninstall-local-tools
|
||||||
go get golang.org/x/tools/cmd/goimports
|
uninstall-local-tools:
|
||||||
|
rm -f $(MYGOBIN)/gorepomod
|
||||||
|
rm -f $(MYGOBIN)/k8scopy
|
||||||
|
rm -f $(MYGOBIN)/pluginator
|
||||||
|
|
||||||
# Build from local source.
|
# Build from local source.
|
||||||
$(MYGOBIN)/gorepomod:
|
$(MYGOBIN)/gorepomod:
|
||||||
@@ -82,173 +69,93 @@ $(MYGOBIN)/pluginator:
|
|||||||
cd cmd/pluginator; \
|
cd cmd/pluginator; \
|
||||||
go install .
|
go install .
|
||||||
|
|
||||||
|
|
||||||
|
# --- Build targets ---
|
||||||
|
|
||||||
# Build from local source.
|
# Build from local source.
|
||||||
$(MYGOBIN)/kustomize: build-kustomize-api
|
$(MYGOBIN)/kustomize: build-kustomize-api
|
||||||
cd kustomize; \
|
cd kustomize; \
|
||||||
go install .
|
go install .
|
||||||
|
|
||||||
.PHONY: install-tools
|
kustomize: $(MYGOBIN)/kustomize
|
||||||
install-tools: \
|
|
||||||
$(MYGOBIN)/goimports \
|
|
||||||
$(MYGOBIN)/golangci-lint-kustomize \
|
|
||||||
$(MYGOBIN)/gorepomod \
|
|
||||||
$(MYGOBIN)/helmV3 \
|
|
||||||
$(MYGOBIN)/k8scopy \
|
|
||||||
$(MYGOBIN)/mdrip \
|
|
||||||
$(MYGOBIN)/pluginator \
|
|
||||||
$(MYGOBIN)/stringer
|
|
||||||
|
|
||||||
### Begin kustomize plugin rules.
|
|
||||||
#
|
|
||||||
# The rules to deal with builtin plugins are a bit
|
|
||||||
# complicated because
|
|
||||||
#
|
|
||||||
# - Every builtin plugin is a Go plugin -
|
|
||||||
# meaning it gets its own module directory
|
|
||||||
# (outside of the api module) with Go
|
|
||||||
# code in a 'main' package per Go plugin rules.
|
|
||||||
# - kustomize locates plugins using the
|
|
||||||
# 'apiVersion' and 'kind' fields from the
|
|
||||||
# plugin config file.
|
|
||||||
# - k8s wants CamelCase in 'kind' fields.
|
|
||||||
# - The module name (the last name in the path)
|
|
||||||
# must be the lowercased 'kind' of the
|
|
||||||
# plugin because Go and related tools
|
|
||||||
# demand lowercase in import paths, but
|
|
||||||
# allow CamelCase in file names.
|
|
||||||
# - the generated code must live in the api
|
|
||||||
# module (it's linked into the api).
|
|
||||||
|
|
||||||
# Where all generated builtin plugin code should go.
|
|
||||||
pGen=api/internal/builtins
|
|
||||||
# Where the builtin Go plugin modules live.
|
|
||||||
pSrc=plugin/builtin
|
|
||||||
|
|
||||||
_builtinplugins = \
|
|
||||||
AnnotationsTransformer.go \
|
|
||||||
ConfigMapGenerator.go \
|
|
||||||
IAMPolicyGenerator.go \
|
|
||||||
HashTransformer.go \
|
|
||||||
ImageTagTransformer.go \
|
|
||||||
LabelTransformer.go \
|
|
||||||
LegacyOrderTransformer.go \
|
|
||||||
NamespaceTransformer.go \
|
|
||||||
PatchJson6902Transformer.go \
|
|
||||||
PatchStrategicMergeTransformer.go \
|
|
||||||
PatchTransformer.go \
|
|
||||||
PrefixTransformer.go \
|
|
||||||
SuffixTransformer.go \
|
|
||||||
ReplacementTransformer.go \
|
|
||||||
ReplicaCountTransformer.go \
|
|
||||||
SecretGenerator.go \
|
|
||||||
ValueAddTransformer.go \
|
|
||||||
HelmChartInflationGenerator.go
|
|
||||||
|
|
||||||
# Maintaining this explicit list of generated files, and
|
|
||||||
# adding it as a dependency to a few targets, to assure
|
|
||||||
# they get recreated if deleted. The rules below on how
|
|
||||||
# to make them don't, by themselves, assure they will be
|
|
||||||
# recreated if deleted.
|
|
||||||
builtinplugins = $(patsubst %,$(pGen)/%,$(_builtinplugins))
|
|
||||||
|
|
||||||
# These rules are verbose, but assure that if a source file
|
|
||||||
# is modified, the corresponding generated file, and only
|
|
||||||
# that file, will be recreated.
|
|
||||||
$(pGen)/AnnotationsTransformer.go: $(pSrc)/annotationstransformer/AnnotationsTransformer.go
|
|
||||||
$(pGen)/ConfigMapGenerator.go: $(pSrc)/configmapgenerator/ConfigMapGenerator.go
|
|
||||||
$(pGen)/GkeSaGenerator.go: $(pSrc)/gkesagenerator/GkeSaGenerator.go
|
|
||||||
$(pGen)/HashTransformer.go: $(pSrc)/hashtransformer/HashTransformer.go
|
|
||||||
$(pGen)/ImageTagTransformer.go: $(pSrc)/imagetagtransformer/ImageTagTransformer.go
|
|
||||||
$(pGen)/LabelTransformer.go: $(pSrc)/labeltransformer/LabelTransformer.go
|
|
||||||
$(pGen)/LegacyOrderTransformer.go: $(pSrc)/legacyordertransformer/LegacyOrderTransformer.go
|
|
||||||
$(pGen)/NamespaceTransformer.go: $(pSrc)/namespacetransformer/NamespaceTransformer.go
|
|
||||||
$(pGen)/PatchJson6902Transformer.go: $(pSrc)/patchjson6902transformer/PatchJson6902Transformer.go
|
|
||||||
$(pGen)/PatchStrategicMergeTransformer.go: $(pSrc)/patchstrategicmergetransformer/PatchStrategicMergeTransformer.go
|
|
||||||
$(pGen)/PatchTransformer.go: $(pSrc)/patchtransformer/PatchTransformer.go
|
|
||||||
$(pGen)/PrefixTransformer.go: $(pSrc)/prefixtransformer/PrefixTransformer.go
|
|
||||||
$(pGen)/SuffixTransformer.go: $(pSrc)/suffixtransformer/SuffixTransformer.go
|
|
||||||
$(pGen)/ReplacementTransformer.go: $(pSrc)/replacementtransformer/ReplacementTransformer.go
|
|
||||||
$(pGen)/ReplicaCountTransformer.go: $(pSrc)/replicacounttransformer/ReplicaCountTransformer.go
|
|
||||||
$(pGen)/SecretGenerator.go: $(pSrc)/secretgenerator/SecretGenerator.go
|
|
||||||
$(pGen)/ValueAddTransformer.go: $(pSrc)/valueaddtransformer/ValueAddTransformer.go
|
|
||||||
$(pGen)/HelmChartInflationGenerator.go: $(pSrc)/helmchartinflationgenerator/HelmChartInflationGenerator.go
|
|
||||||
|
|
||||||
# The (verbose but portable) Makefile way to convert to lowercase.
|
|
||||||
toLowerCase = $(subst A,a,$(subst B,b,$(subst C,c,$(subst D,d,$(subst E,e,$(subst F,f,$(subst G,g,$(subst H,h,$(subst I,i,$(subst J,j,$(subst K,k,$(subst L,l,$(subst M,m,$(subst N,n,$(subst O,o,$(subst P,p,$(subst Q,q,$(subst R,r,$(subst S,s,$(subst T,t,$(subst U,u,$(subst V,v,$(subst W,w,$(subst X,x,$(subst Y,y,$(subst Z,z,$1))))))))))))))))))))))))))
|
|
||||||
|
|
||||||
$(pGen)/%.go: $(MYGOBIN)/pluginator
|
|
||||||
@echo "generating $*"
|
|
||||||
( \
|
|
||||||
set -e; \
|
|
||||||
cd $(pSrc)/$(call toLowerCase,$*); \
|
|
||||||
go generate .; \
|
|
||||||
cd ../../../$(pGen); \
|
|
||||||
$(MYGOBIN)/goimports -w $*.go \
|
|
||||||
)
|
|
||||||
|
|
||||||
# Target is for debugging.
|
|
||||||
.PHONY: generate-kustomize-builtin-plugins
|
|
||||||
generate-kustomize-builtin-plugins: $(builtinplugins)
|
|
||||||
|
|
||||||
.PHONY: build-kustomize-external-go-plugin
|
|
||||||
build-kustomize-external-go-plugin:
|
|
||||||
./hack/buildExternalGoPlugins.sh ./plugin
|
|
||||||
|
|
||||||
.PHONY: clean-kustomize-external-go-plugin
|
|
||||||
clean-kustomize-external-go-plugin:
|
|
||||||
./hack/buildExternalGoPlugins.sh ./plugin clean
|
|
||||||
|
|
||||||
### End kustomize plugin rules.
|
|
||||||
|
|
||||||
.PHONY: lint-kustomize
|
|
||||||
lint-kustomize: $(MYGOBIN)/golangci-lint-kustomize $(builtinplugins)
|
|
||||||
cd api; $(MYGOBIN)/golangci-lint-kustomize \
|
|
||||||
-c ../.golangci-kustomize.yml \
|
|
||||||
run ./...
|
|
||||||
cd kustomize; $(MYGOBIN)/golangci-lint-kustomize \
|
|
||||||
-c ../.golangci-kustomize.yml \
|
|
||||||
run ./...
|
|
||||||
cd cmd/pluginator; $(MYGOBIN)/golangci-lint-kustomize \
|
|
||||||
-c ../../.golangci-kustomize.yml \
|
|
||||||
run ./...
|
|
||||||
|
|
||||||
# Used to add non-default compilation flags when experimenting with
|
# Used to add non-default compilation flags when experimenting with
|
||||||
# plugin-to-api compatibility checks.
|
# plugin-to-api compatibility checks.
|
||||||
.PHONY: build-kustomize-api
|
.PHONY: build-kustomize-api
|
||||||
build-kustomize-api: $(builtinplugins)
|
build-kustomize-api: $(MYGOBIN)/goimports $(builtinplugins)
|
||||||
cd api; go build ./...
|
cd api; $(MAKE) build
|
||||||
|
|
||||||
.PHONY: generate-kustomize-api
|
.PHONY: generate-kustomize-api
|
||||||
generate-kustomize-api: $(MYGOBIN)/k8scopy
|
generate-kustomize-api:
|
||||||
cd api; go generate ./...
|
cd api; $(MAKE) generate
|
||||||
|
|
||||||
.PHONY: test-unit-kustomize-api
|
|
||||||
test-unit-kustomize-api: build-kustomize-api
|
# --- Verification targets ---
|
||||||
cd api; go test ./... -ldflags "-X sigs.k8s.io/kustomize/api/provenance.version=v444.333.222"
|
.PHONY: verify-kustomize-repo
|
||||||
cd api/krusty; OPENAPI_TEST=true go test -run TestCustomOpenAPIFieldFromComponentWithOverlays
|
verify-kustomize-repo: \
|
||||||
|
install-tools \
|
||||||
|
lint \
|
||||||
|
check-license \
|
||||||
|
test-unit-all \
|
||||||
|
build-non-plugin-all \
|
||||||
|
test-go-mod \
|
||||||
|
test-examples-kustomize-against-HEAD \
|
||||||
|
test-examples-kustomize-against-v4-release
|
||||||
|
|
||||||
|
# The following target referenced by a file in
|
||||||
|
# https://github.com/kubernetes/test-infra/tree/master/config/jobs/kubernetes-sigs/kustomize
|
||||||
|
.PHONY: prow-presubmit-check
|
||||||
|
prow-presubmit-check: \
|
||||||
|
install-tools \
|
||||||
|
test-unit-kustomize-plugins \
|
||||||
|
test-go-mod \
|
||||||
|
build-non-plugin-all \
|
||||||
|
test-examples-kustomize-against-HEAD \
|
||||||
|
test-examples-kustomize-against-v4-release
|
||||||
|
|
||||||
|
.PHONY: license
|
||||||
|
license: $(MYGOBIN)/addlicense
|
||||||
|
./hack/add-license.sh run
|
||||||
|
|
||||||
|
.PHONY: check-license
|
||||||
|
check-license: $(MYGOBIN)/addlicense
|
||||||
|
./hack/add-license.sh check
|
||||||
|
|
||||||
|
.PHONY: lint
|
||||||
|
lint: $(MYGOBIN)/golangci-lint $(MYGOBIN)/goimports $(builtinplugins)
|
||||||
|
./hack/for-each-module.sh "make lint"
|
||||||
|
|
||||||
|
.PHONY: test-unit-all
|
||||||
|
test-unit-all: \
|
||||||
|
test-unit-non-plugin \
|
||||||
|
test-unit-kustomize-plugins
|
||||||
|
|
||||||
|
# This target is used by our Github Actions CI to run unit tests for all non-plugin modules in multiple GOOS environments.
|
||||||
|
.PHONY: test-unit-non-plugin
|
||||||
|
test-unit-non-plugin:
|
||||||
|
./hack/for-each-module.sh "make test" "./plugin/*" 15
|
||||||
|
|
||||||
|
.PHONY: build-non-plugin-all
|
||||||
|
build-non-plugin-all:
|
||||||
|
./hack/for-each-module.sh "make build" "./plugin/*" 15
|
||||||
|
|
||||||
.PHONY: test-unit-kustomize-plugins
|
.PHONY: test-unit-kustomize-plugins
|
||||||
test-unit-kustomize-plugins:
|
test-unit-kustomize-plugins:
|
||||||
./hack/testUnitKustomizePlugins.sh
|
./hack/testUnitKustomizePlugins.sh
|
||||||
|
|
||||||
.PHONY: test-unit-kustomize-cli
|
.PHONY: functions-examples-all
|
||||||
test-unit-kustomize-cli:
|
functions-examples-all:
|
||||||
cd kustomize; go test ./...
|
for dir in $(abspath $(wildcard functions/examples/*/.)); do \
|
||||||
|
echo -e "\n---Running make tasks for function $$dir---"; \
|
||||||
.PHONY: test-unit-kustomize-all
|
set -e; \
|
||||||
test-unit-kustomize-all: \
|
cd $$dir; $(MAKE) all; \
|
||||||
test-unit-kustomize-api \
|
done
|
||||||
test-unit-kustomize-cli \
|
|
||||||
test-unit-kustomize-plugins
|
|
||||||
|
|
||||||
test-unit-cmd-all:
|
|
||||||
./hack/kyaml-pre-commit.sh
|
|
||||||
|
|
||||||
test-go-mod:
|
test-go-mod:
|
||||||
./hack/check-go-mod.sh
|
./hack/for-each-module.sh "go list -m -json all > /dev/null && go mod tidy -v"
|
||||||
|
|
||||||
.PHONY:
|
.PHONY:
|
||||||
test-examples-e2e-kustomize: $(MYGOBIN)/mdrip $(MYGOBIN)/kind
|
verify-kustomize-e2e: $(MYGOBIN)/mdrip $(MYGOBIN)/kind
|
||||||
( \
|
( \
|
||||||
set -e; \
|
set -e; \
|
||||||
/bin/rm -f $(MYGOBIN)/kustomize; \
|
/bin/rm -f $(MYGOBIN)/kustomize; \
|
||||||
@@ -265,85 +172,13 @@ test-examples-kustomize-against-HEAD: $(MYGOBIN)/kustomize $(MYGOBIN)/mdrip
|
|||||||
test-examples-kustomize-against-v4-release: $(MYGOBIN)/mdrip
|
test-examples-kustomize-against-v4-release: $(MYGOBIN)/mdrip
|
||||||
./hack/testExamplesAgainstKustomize.sh v4@$(LATEST_V4_RELEASE)
|
./hack/testExamplesAgainstKustomize.sh v4@$(LATEST_V4_RELEASE)
|
||||||
|
|
||||||
# linux only.
|
|
||||||
# This is for testing an example plugin that
|
|
||||||
# uses kubeval for validation.
|
|
||||||
# Don't want to add a hard dependence in go.mod file
|
|
||||||
# to github.com/instrumenta/kubeval.
|
|
||||||
# Instead, download the binary.
|
|
||||||
$(MYGOBIN)/kubeval:
|
|
||||||
( \
|
|
||||||
set -e; \
|
|
||||||
d=$(shell mktemp -d); cd $$d; \
|
|
||||||
wget https://github.com/instrumenta/kubeval/releases/latest/download/kubeval-$(GOOS)-$(GOARCH).tar.gz; \
|
|
||||||
tar xf kubeval-$(GOOS)-$(GOARCH).tar.gz; \
|
|
||||||
mv kubeval $(MYGOBIN); \
|
|
||||||
rm -rf $$d; \
|
|
||||||
)
|
|
||||||
|
|
||||||
# linux only.
|
|
||||||
# This is for testing an example plugin that uses helm to inflate a chart
|
|
||||||
# for subsequent kustomization.
|
|
||||||
# Don't want to add a hard dependence in go.mod file to helm.
|
|
||||||
# Instead, download the binaries.
|
|
||||||
$(MYGOBIN)/helmV2:
|
|
||||||
( \
|
|
||||||
set -e; \
|
|
||||||
d=$(shell mktemp -d); cd $$d; \
|
|
||||||
tgzFile=helm-v2.13.1-$(GOOS)-$(GOARCH).tar.gz; \
|
|
||||||
wget https://storage.googleapis.com/kubernetes-helm/$$tgzFile; \
|
|
||||||
tar -xvzf $$tgzFile; \
|
|
||||||
mv $(GOOS)-$(GOARCH)/helm $(MYGOBIN)/helmV2; \
|
|
||||||
rm -rf $$d \
|
|
||||||
)
|
|
||||||
|
|
||||||
# Helm V3 differs from helm V2; downloading it to provide coverage for the
|
|
||||||
# chart inflator plugin under helm v3.
|
|
||||||
$(MYGOBIN)/helmV3:
|
|
||||||
( \
|
|
||||||
set -e; \
|
|
||||||
d=$(shell mktemp -d); cd $$d; \
|
|
||||||
tgzFile=helm-v3.6.3-$(GOOS)-$(GOARCH).tar.gz; \
|
|
||||||
wget https://get.helm.sh/$$tgzFile; \
|
|
||||||
tar -xvzf $$tgzFile; \
|
|
||||||
mv $(GOOS)-$(GOARCH)/helm $(MYGOBIN)/helmV3; \
|
|
||||||
rm -rf $$d \
|
|
||||||
)
|
|
||||||
|
|
||||||
$(MYGOBIN)/kind:
|
|
||||||
( \
|
|
||||||
set -e; \
|
|
||||||
d=$(shell mktemp -d); cd $$d; \
|
|
||||||
wget -O ./kind https://github.com/kubernetes-sigs/kind/releases/download/v0.7.0/kind-$(GOOS)-$(GOARCH); \
|
|
||||||
chmod +x ./kind; \
|
|
||||||
mv ./kind $(MYGOBIN); \
|
|
||||||
rm -rf $$d; \
|
|
||||||
)
|
|
||||||
|
|
||||||
# linux only.
|
|
||||||
$(MYGOBIN)/gh:
|
|
||||||
( \
|
|
||||||
set -e; \
|
|
||||||
d=$(shell mktemp -d); cd $$d; \
|
|
||||||
tgzFile=gh_1.0.0_$(GOOS)_$(GOARCH).tar.gz; \
|
|
||||||
wget https://github.com/cli/cli/releases/download/v1.0.0/$$tgzFile; \
|
|
||||||
tar -xvzf $$tgzFile; \
|
|
||||||
mv gh_1.0.0_$(GOOS)_$(GOARCH)/bin/gh $(MYGOBIN)/gh; \
|
|
||||||
rm -rf $$d \
|
|
||||||
)
|
|
||||||
|
|
||||||
|
# --- Cleanup targets ---
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean: clean-kustomize-external-go-plugin
|
clean: clean-kustomize-external-go-plugin uninstall-tools
|
||||||
go clean --cache
|
go clean --cache
|
||||||
rm -f $(builtinplugins)
|
rm -f $(builtinplugins)
|
||||||
rm -f $(MYGOBIN)/goimports
|
|
||||||
rm -f $(MYGOBIN)/golangci-lint-kustomize
|
|
||||||
rm -f $(MYGOBIN)/kustomize
|
rm -f $(MYGOBIN)/kustomize
|
||||||
rm -f $(MYGOBIN)/mdrip
|
|
||||||
rm -f $(MYGOBIN)/stringer
|
|
||||||
|
|
||||||
# Handle pluginator manually.
|
|
||||||
# rm -f $(MYGOBIN)/pluginator
|
|
||||||
|
|
||||||
# Nuke the site from orbit. It's the only way to be sure.
|
# Nuke the site from orbit. It's the only way to be sure.
|
||||||
.PHONY: nuke
|
.PHONY: nuke
|
||||||
|
|||||||
38
Makefile-modules.mk
Normal file
38
Makefile-modules.mk
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
# Copyright 2022 The Kubernetes Authors.
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
MYGOBIN = $(shell go env GOBIN)
|
||||||
|
ifeq ($(MYGOBIN),)
|
||||||
|
MYGOBIN = $(shell go env GOPATH)/bin
|
||||||
|
endif
|
||||||
|
export PATH := $(MYGOBIN):$(PATH)
|
||||||
|
|
||||||
|
# only set this if not already set, so importing makefiles can override it
|
||||||
|
export KUSTOMIZE_ROOT ?= $(shell pwd | sed -E 's|(.*\/kustomize)/(.*)|\1|')
|
||||||
|
include $(KUSTOMIZE_ROOT)/Makefile-tools.mk
|
||||||
|
|
||||||
|
.PHONY: lint test fix fmt tidy vet build
|
||||||
|
|
||||||
|
lint: $(MYGOBIN)/golangci-lint
|
||||||
|
$(MYGOBIN)/golangci-lint \
|
||||||
|
-c $$KUSTOMIZE_ROOT/.golangci.yml \
|
||||||
|
--path-prefix $(shell pwd | sed -E 's|(.*\/kustomize)/(.*)|\2|') \
|
||||||
|
run ./...
|
||||||
|
|
||||||
|
test:
|
||||||
|
go test -v -timeout 45m -cover ./...
|
||||||
|
|
||||||
|
fix:
|
||||||
|
go fix ./...
|
||||||
|
|
||||||
|
fmt:
|
||||||
|
go fmt ./...
|
||||||
|
|
||||||
|
tidy:
|
||||||
|
go mod tidy
|
||||||
|
|
||||||
|
vet:
|
||||||
|
go vet ./...
|
||||||
|
|
||||||
|
build:
|
||||||
|
go build -v -o $(MYGOBIN) ./...
|
||||||
102
Makefile-plugins.mk
Normal file
102
Makefile-plugins.mk
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
# Copyright 2022 The Kubernetes Authors.
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
### Kustomize plugin rules.
|
||||||
|
#
|
||||||
|
# The rules to deal with builtin plugins are a bit
|
||||||
|
# complicated because
|
||||||
|
#
|
||||||
|
# - Every builtin plugin is a Go plugin -
|
||||||
|
# meaning it gets its own module directory
|
||||||
|
# (outside of the api module) with Go
|
||||||
|
# code in a 'main' package per Go plugin rules.
|
||||||
|
# - kustomize locates plugins using the
|
||||||
|
# 'apiVersion' and 'kind' fields from the
|
||||||
|
# plugin config file.
|
||||||
|
# - k8s wants CamelCase in 'kind' fields.
|
||||||
|
# - The module name (the last name in the path)
|
||||||
|
# must be the lowercased 'kind' of the
|
||||||
|
# plugin because Go and related tools
|
||||||
|
# demand lowercase in import paths, but
|
||||||
|
# allow CamelCase in file names.
|
||||||
|
# - the generated code must live in the api
|
||||||
|
# module (it's linked into the api).
|
||||||
|
|
||||||
|
# Where all generated builtin plugin code should go.
|
||||||
|
pGen=api/internal/builtins
|
||||||
|
# Where the builtin Go plugin modules live.
|
||||||
|
pSrc=plugin/builtin
|
||||||
|
|
||||||
|
_builtinplugins = \
|
||||||
|
AnnotationsTransformer.go \
|
||||||
|
ConfigMapGenerator.go \
|
||||||
|
IAMPolicyGenerator.go \
|
||||||
|
HashTransformer.go \
|
||||||
|
ImageTagTransformer.go \
|
||||||
|
LabelTransformer.go \
|
||||||
|
LegacyOrderTransformer.go \
|
||||||
|
NamespaceTransformer.go \
|
||||||
|
PatchJson6902Transformer.go \
|
||||||
|
PatchStrategicMergeTransformer.go \
|
||||||
|
PatchTransformer.go \
|
||||||
|
PrefixTransformer.go \
|
||||||
|
SuffixTransformer.go \
|
||||||
|
ReplacementTransformer.go \
|
||||||
|
ReplicaCountTransformer.go \
|
||||||
|
SecretGenerator.go \
|
||||||
|
ValueAddTransformer.go \
|
||||||
|
HelmChartInflationGenerator.go
|
||||||
|
|
||||||
|
# Maintaining this explicit list of generated files, and
|
||||||
|
# adding it as a dependency to a few targets, to assure
|
||||||
|
# they get recreated if deleted. The rules below on how
|
||||||
|
# to make them don't, by themselves, assure they will be
|
||||||
|
# recreated if deleted.
|
||||||
|
builtinplugins = $(patsubst %,$(pGen)/%,$(_builtinplugins))
|
||||||
|
|
||||||
|
# These rules are verbose, but assure that if a source file
|
||||||
|
# is modified, the corresponding generated file, and only
|
||||||
|
# that file, will be recreated.
|
||||||
|
$(pGen)/AnnotationsTransformer.go: $(pSrc)/annotationstransformer/AnnotationsTransformer.go
|
||||||
|
$(pGen)/ConfigMapGenerator.go: $(pSrc)/configmapgenerator/ConfigMapGenerator.go
|
||||||
|
$(pGen)/GkeSaGenerator.go: $(pSrc)/gkesagenerator/GkeSaGenerator.go
|
||||||
|
$(pGen)/HashTransformer.go: $(pSrc)/hashtransformer/HashTransformer.go
|
||||||
|
$(pGen)/ImageTagTransformer.go: $(pSrc)/imagetagtransformer/ImageTagTransformer.go
|
||||||
|
$(pGen)/LabelTransformer.go: $(pSrc)/labeltransformer/LabelTransformer.go
|
||||||
|
$(pGen)/LegacyOrderTransformer.go: $(pSrc)/legacyordertransformer/LegacyOrderTransformer.go
|
||||||
|
$(pGen)/NamespaceTransformer.go: $(pSrc)/namespacetransformer/NamespaceTransformer.go
|
||||||
|
$(pGen)/PatchJson6902Transformer.go: $(pSrc)/patchjson6902transformer/PatchJson6902Transformer.go
|
||||||
|
$(pGen)/PatchStrategicMergeTransformer.go: $(pSrc)/patchstrategicmergetransformer/PatchStrategicMergeTransformer.go
|
||||||
|
$(pGen)/PatchTransformer.go: $(pSrc)/patchtransformer/PatchTransformer.go
|
||||||
|
$(pGen)/PrefixTransformer.go: $(pSrc)/prefixtransformer/PrefixTransformer.go
|
||||||
|
$(pGen)/SuffixTransformer.go: $(pSrc)/suffixtransformer/SuffixTransformer.go
|
||||||
|
$(pGen)/ReplacementTransformer.go: $(pSrc)/replacementtransformer/ReplacementTransformer.go
|
||||||
|
$(pGen)/ReplicaCountTransformer.go: $(pSrc)/replicacounttransformer/ReplicaCountTransformer.go
|
||||||
|
$(pGen)/SecretGenerator.go: $(pSrc)/secretgenerator/SecretGenerator.go
|
||||||
|
$(pGen)/ValueAddTransformer.go: $(pSrc)/valueaddtransformer/ValueAddTransformer.go
|
||||||
|
$(pGen)/HelmChartInflationGenerator.go: $(pSrc)/helmchartinflationgenerator/HelmChartInflationGenerator.go
|
||||||
|
|
||||||
|
# The (verbose but portable) Makefile way to convert to lowercase.
|
||||||
|
toLowerCase = $(subst A,a,$(subst B,b,$(subst C,c,$(subst D,d,$(subst E,e,$(subst F,f,$(subst G,g,$(subst H,h,$(subst I,i,$(subst J,j,$(subst K,k,$(subst L,l,$(subst M,m,$(subst N,n,$(subst O,o,$(subst P,p,$(subst Q,q,$(subst R,r,$(subst S,s,$(subst T,t,$(subst U,u,$(subst V,v,$(subst W,w,$(subst X,x,$(subst Y,y,$(subst Z,z,$1))))))))))))))))))))))))))
|
||||||
|
|
||||||
|
$(pGen)/%.go: $(MYGOBIN)/pluginator
|
||||||
|
@echo "generating $*"
|
||||||
|
( \
|
||||||
|
set -e; \
|
||||||
|
cd $(pSrc)/$(call toLowerCase,$*); \
|
||||||
|
go generate .; \
|
||||||
|
cd ../../../$(pGen); \
|
||||||
|
$(MYGOBIN)/goimports -w $*.go \
|
||||||
|
)
|
||||||
|
|
||||||
|
# Target is for debugging.
|
||||||
|
.PHONY: generate-kustomize-builtin-plugins
|
||||||
|
generate-kustomize-builtin-plugins: $(builtinplugins)
|
||||||
|
|
||||||
|
.PHONY: build-kustomize-external-go-plugin
|
||||||
|
build-kustomize-external-go-plugin:
|
||||||
|
./hack/buildExternalGoPlugins.sh ./plugin
|
||||||
|
|
||||||
|
.PHONY: clean-kustomize-external-go-plugin
|
||||||
|
clean-kustomize-external-go-plugin:
|
||||||
|
./hack/buildExternalGoPlugins.sh ./plugin clean
|
||||||
100
Makefile-tools.mk
Normal file
100
Makefile-tools.mk
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
# Copyright 2022 The Kubernetes Authors.
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
MYGOBIN = $(shell go env GOBIN)
|
||||||
|
ifeq ($(MYGOBIN),)
|
||||||
|
MYGOBIN = $(shell go env GOPATH)/bin
|
||||||
|
endif
|
||||||
|
export PATH := $(MYGOBIN):$(PATH)
|
||||||
|
|
||||||
|
.PHONY: install-out-of-tree-tools
|
||||||
|
install-out-of-tree-tools: \
|
||||||
|
$(MYGOBIN)/goimports \
|
||||||
|
$(MYGOBIN)/golangci-lint \
|
||||||
|
$(MYGOBIN)/helmV3 \
|
||||||
|
$(MYGOBIN)/mdrip \
|
||||||
|
$(MYGOBIN)/stringer \
|
||||||
|
$(MYGOBIN)/goimports
|
||||||
|
|
||||||
|
.PHONY: uninstall-out-of-tree-tools
|
||||||
|
uninstall-out-of-tree-tools:
|
||||||
|
rm -f $(MYGOBIN)/goimports
|
||||||
|
rm -f $(MYGOBIN)/golangci-lint
|
||||||
|
rm -f $(MYGOBIN)/helmV3
|
||||||
|
rm -f $(MYGOBIN)/mdrip
|
||||||
|
rm -f $(MYGOBIN)/stringer
|
||||||
|
|
||||||
|
$(MYGOBIN)/golangci-lint:
|
||||||
|
go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.45.2
|
||||||
|
|
||||||
|
$(MYGOBIN)/mdrip:
|
||||||
|
go install github.com/monopole/mdrip@v1.0.2
|
||||||
|
|
||||||
|
$(MYGOBIN)/stringer:
|
||||||
|
go install golang.org/x/tools/cmd/stringer@latest
|
||||||
|
|
||||||
|
$(MYGOBIN)/goimports:
|
||||||
|
go install golang.org/x/tools/cmd/goimports@latest
|
||||||
|
|
||||||
|
$(MYGOBIN)/mdtogo:
|
||||||
|
go install sigs.k8s.io/kustomize/cmd/mdtogo@latest
|
||||||
|
|
||||||
|
$(MYGOBIN)/addlicense:
|
||||||
|
go install github.com/google/addlicense@latest
|
||||||
|
|
||||||
|
$(MYGOBIN)/statik:
|
||||||
|
go install github.com/rakyll/statik@latest
|
||||||
|
|
||||||
|
$(MYGOBIN)/goreleaser:
|
||||||
|
go install github.com/goreleaser/goreleaser@v0.179.0 # https://github.com/kubernetes-sigs/kustomize/issues/4542
|
||||||
|
|
||||||
|
$(MYGOBIN)/kind:
|
||||||
|
( \
|
||||||
|
set -e; \
|
||||||
|
d=$(shell mktemp -d); cd $$d; \
|
||||||
|
wget -O ./kind https://github.com/kubernetes-sigs/kind/releases/download/v0.7.0/kind-$(GOOS)-$(GOARCH); \
|
||||||
|
chmod +x ./kind; \
|
||||||
|
mv ./kind $(MYGOBIN); \
|
||||||
|
rm -rf $$d; \
|
||||||
|
)
|
||||||
|
|
||||||
|
# linux only.
|
||||||
|
$(MYGOBIN)/gh:
|
||||||
|
( \
|
||||||
|
set -e; \
|
||||||
|
d=$(shell mktemp -d); cd $$d; \
|
||||||
|
tgzFile=gh_1.0.0_$(GOOS)_$(GOARCH).tar.gz; \
|
||||||
|
wget https://github.com/cli/cli/releases/download/v1.0.0/$$tgzFile; \
|
||||||
|
tar -xvzf $$tgzFile; \
|
||||||
|
mv gh_1.0.0_$(GOOS)_$(GOARCH)/bin/gh $(MYGOBIN)/gh; \
|
||||||
|
rm -rf $$d \
|
||||||
|
)
|
||||||
|
|
||||||
|
# linux only.
|
||||||
|
# This is for testing an example plugin that
|
||||||
|
# uses kubeval for validation.
|
||||||
|
# Don't want to add a hard dependence in go.mod file
|
||||||
|
# to github.com/instrumenta/kubeval.
|
||||||
|
# Instead, download the binary.
|
||||||
|
$(MYGOBIN)/kubeval:
|
||||||
|
( \
|
||||||
|
set -e; \
|
||||||
|
d=$(shell mktemp -d); cd $$d; \
|
||||||
|
wget https://github.com/instrumenta/kubeval/releases/latest/download/kubeval-$(GOOS)-$(GOARCH).tar.gz; \
|
||||||
|
tar xf kubeval-$(GOOS)-$(GOARCH).tar.gz; \
|
||||||
|
mv kubeval $(MYGOBIN); \
|
||||||
|
rm -rf $$d; \
|
||||||
|
)
|
||||||
|
|
||||||
|
# Helm V3 differs from helm V2; downloading it to provide coverage for the
|
||||||
|
# chart inflator plugin under helm v3.
|
||||||
|
$(MYGOBIN)/helmV3:
|
||||||
|
( \
|
||||||
|
set -e; \
|
||||||
|
d=$(shell mktemp -d); cd $$d; \
|
||||||
|
tgzFile=helm-v3.6.3-$(GOOS)-$(GOARCH).tar.gz; \
|
||||||
|
wget https://get.helm.sh/$$tgzFile; \
|
||||||
|
tar -xvzf $$tgzFile; \
|
||||||
|
mv $(GOOS)-$(GOARCH)/helm $(MYGOBIN)/helmV3; \
|
||||||
|
rm -rf $$d \
|
||||||
|
)
|
||||||
44
README.md
44
README.md
@@ -11,8 +11,8 @@ and it's like [`sed`], in that it emits edited text.
|
|||||||
|
|
||||||
This tool is sponsored by [sig-cli] ([KEP]).
|
This tool is sponsored by [sig-cli] ([KEP]).
|
||||||
|
|
||||||
- [Installation instructions](https://kubernetes-sigs.github.io/kustomize/installation)
|
- [Installation instructions](https://kubectl.docs.kubernetes.io/installation/kustomize/)
|
||||||
- [General documentation](https://kubernetes-sigs.github.io/kustomize)
|
- [General documentation](https://kubectl.docs.kubernetes.io/references/kustomize/)
|
||||||
- [Examples](examples)
|
- [Examples](examples)
|
||||||
|
|
||||||
[](https://prow.k8s.io/job-history/kubernetes-jenkins/pr-logs/directory/kustomize-presubmit-master)
|
[](https://prow.k8s.io/job-history/kubernetes-jenkins/pr-logs/directory/kustomize-presubmit-master)
|
||||||
@@ -34,13 +34,13 @@ will be reflected in the Kubernetes release notes.
|
|||||||
| v1.21 | v4.0.5 |
|
| v1.21 | v4.0.5 |
|
||||||
| v1.22 | v4.2.0 |
|
| v1.22 | v4.2.0 |
|
||||||
|
|
||||||
[v2.0.3]: /../../tree/v2.0.3
|
[v2.0.3]: https://github.com/kubernetes-sigs/kustomize/releases/tag/v2.0.3
|
||||||
[#2506]: https://github.com/kubernetes-sigs/kustomize/issues/2506
|
[#2506]: https://github.com/kubernetes-sigs/kustomize/issues/2506
|
||||||
[#1500]: https://github.com/kubernetes-sigs/kustomize/issues/1500
|
[#1500]: https://github.com/kubernetes-sigs/kustomize/issues/1500
|
||||||
[kust-in-kubectl update]: https://github.com/kubernetes/kubernetes/blob/4d75a6238a6e330337526e0513e67d02b1940b63/CHANGELOG/CHANGELOG-1.21.md#kustomize-updates-in-kubectl
|
[kust-in-kubectl update]: https://github.com/kubernetes/kubernetes/blob/4d75a6238a6e330337526e0513e67d02b1940b63/CHANGELOG/CHANGELOG-1.21.md#kustomize-updates-in-kubectl
|
||||||
|
|
||||||
For examples and guides for using the kubectl integration please
|
For examples and guides for using the kubectl integration please
|
||||||
see the [kubectl book] or the [kubernetes documentation].
|
see the [kubernetes documentation].
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
@@ -141,8 +141,9 @@ The YAML can be directly [applied] to a cluster:
|
|||||||
|
|
||||||
## Community
|
## Community
|
||||||
|
|
||||||
- [file a bug](https://kubernetes-sigs.github.io/kustomize/contributing/bugs/) instructions
|
- [file a bug](https://kubectl.docs.kubernetes.io/contributing/kustomize/bugs/)
|
||||||
- [contribute a feature](https://kubernetes-sigs.github.io/kustomize/contributing/features/) instructions
|
- [contribute a feature](https://kubectl.docs.kubernetes.io/contributing/kustomize/features/)
|
||||||
|
- [propose a larger enhancement](https://github.com/kubernetes-sigs/kustomize/tree/master/proposals)
|
||||||
|
|
||||||
### Code of conduct
|
### Code of conduct
|
||||||
|
|
||||||
@@ -151,27 +152,22 @@ is governed by the [Kubernetes Code of Conduct].
|
|||||||
|
|
||||||
[`make`]: https://www.gnu.org/software/make
|
[`make`]: https://www.gnu.org/software/make
|
||||||
[`sed`]: https://www.gnu.org/software/sed
|
[`sed`]: https://www.gnu.org/software/sed
|
||||||
[DAM]: https://kubernetes-sigs.github.io/kustomize/api-reference/glossary#declarative-application-management
|
[DAM]: https://kubectl.docs.kubernetes.io/references/kustomize/glossary/#declarative-application-management
|
||||||
[KEP]: https://github.com/kubernetes/enhancements/blob/master/keps/sig-cli/2377-Kustomize/README.md
|
[KEP]: https://github.com/kubernetes/enhancements/blob/master/keps/sig-cli/2377-Kustomize/README.md
|
||||||
[Kubernetes Code of Conduct]: code-of-conduct.md
|
[Kubernetes Code of Conduct]: code-of-conduct.md
|
||||||
[applied]: https://kubernetes-sigs.github.io/kustomize/api-reference/glossary#apply
|
[applied]: https://kubectl.docs.kubernetes.io/references/kustomize/glossary/#apply
|
||||||
[base]: https://kubernetes-sigs.github.io/kustomize/api-reference/glossary#base
|
[base]: https://kubectl.docs.kubernetes.io/references/kustomize/glossary/#base
|
||||||
[declarative configuration]: https://kubernetes-sigs.github.io/kustomize/api-reference/glossary#declarative-application-management
|
[declarative configuration]: https://kubectl.docs.kubernetes.io/references/kustomize/glossary/#declarative-application-management
|
||||||
[imageBase]: docs/images/base.jpg
|
[imageBase]: images/base.jpg
|
||||||
[imageOverlay]: docs/images/overlay.jpg
|
[imageOverlay]: images/overlay.jpg
|
||||||
[kubectl announcement]: 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/guides/introduction/kustomize/
|
|
||||||
[kubernetes documentation]: https://kubernetes.io/docs/tasks/manage-kubernetes-objects/kustomization/
|
[kubernetes documentation]: https://kubernetes.io/docs/tasks/manage-kubernetes-objects/kustomization/
|
||||||
[kubernetes style]: https://kubernetes-sigs.github.io/kustomize/api-reference/glossary#kubernetes-style-object
|
[kubernetes style]: https://kubectl.docs.kubernetes.io/references/kustomize/glossary/#kubernetes-style-object
|
||||||
[kustomization]: https://kubernetes-sigs.github.io/kustomize/api-reference/glossary#kustomization
|
[kustomization]: https://kubectl.docs.kubernetes.io/references/kustomize/glossary/#kustomization
|
||||||
[overlay]: https://kubernetes-sigs.github.io/kustomize/api-reference/glossary#overlay
|
[overlay]: https://kubectl.docs.kubernetes.io/references/kustomize/glossary/#overlay
|
||||||
[overlays]: https://kubernetes-sigs.github.io/kustomize/api-reference/glossary#overlay
|
[overlays]: https://kubectl.docs.kubernetes.io/references/kustomize/glossary/#overlay
|
||||||
[release page]: https://github.com/kubernetes-sigs/kustomize/releases
|
[release page]: https://github.com/kubernetes-sigs/kustomize/releases
|
||||||
[resource]: https://kubernetes-sigs.github.io/kustomize/api-reference/glossary#resource
|
[resource]: https://kubectl.docs.kubernetes.io/references/kustomize/glossary/#resource
|
||||||
[resources]: https://kubernetes-sigs.github.io/kustomize/api-reference/glossary#resource
|
[resources]: https://kubectl.docs.kubernetes.io/references/kustomize/glossary/#resource
|
||||||
[sig-cli]: https://github.com/kubernetes/community/blob/master/sig-cli/README.md
|
[sig-cli]: https://github.com/kubernetes/community/blob/master/sig-cli/README.md
|
||||||
[variant]: https://kubernetes-sigs.github.io/kustomize/api-reference/glossary#variant
|
[variants]: https://kubectl.docs.kubernetes.io/references/kustomize/glossary/#variant
|
||||||
[variants]: https://kubernetes-sigs.github.io/kustomize/api-reference/glossary#variant
|
|
||||||
[v2.0.3]: https://github.com/kubernetes-sigs/kustomize/releases/tag/v2.0.3
|
|
||||||
[v2.1.0]: https://github.com/kubernetes-sigs/kustomize/releases/tag/v2.1.0
|
|
||||||
[workflows]: https://kubernetes-sigs.github.io/kustomize/guides
|
|
||||||
|
|||||||
112
ROADMAP.md
Normal file
112
ROADMAP.md
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
# Kustomize roadmap 2022
|
||||||
|
|
||||||
|
Presented at the [January 26, 2022, SIG-CLI meeting](https://youtu.be/l2plzJ9MRlk?t=1321)
|
||||||
|
|
||||||
|
kustomize maintainers: @knverey, @natasha41575
|
||||||
|
|
||||||
|
[Objective: Improve contributor community](#objective-improve-contributor-community)
|
||||||
|
|
||||||
|
[Objective: Improve end-user experience](#objective-improve-end-user-experience)
|
||||||
|
|
||||||
|
[Objective: Improve extension experience](#objective-improve-extension-experience)
|
||||||
|
|
||||||
|
## Objective: Improve contributor community
|
||||||
|
|
||||||
|
**_WHO: End user who also contributes source code._**
|
||||||
|
|
||||||
|
Top priority:
|
||||||
|
|
||||||
|
- Kustomization v1 (also end-user impact) ([PROJECT](https://github.com/kubernetes-sigs/kustomize/projects/12))
|
||||||
|
- Remove the following fields:
|
||||||
|
- [vars](https://github.com/kubernetes-sigs/kustomize/issues/2052)
|
||||||
|
- [patchesJson6902, patchesStrategicMerge (consolidate on \`patches)](https://github.com/kubernetes-sigs/kustomize/issues/4376)
|
||||||
|
- [helmChartInflationGenerator, helmCharts, helmGlobals](https://github.com/kubernetes-sigs/kustomize/issues/4401)
|
||||||
|
- all long-deprecated fields in Kustomization v1 such as \`bases\` and those being accommodate by kustomize edit \[[see code snippet](https://github.com/kubernetes-sigs/kustomize/blob/ee4b7847f0beb6c0d2070673b10f23f7b3e92e82/api/types/fix.go#L15)\]
|
||||||
|
- Ensure that \`kustomize edit fix\` handles migrations for all those, and that anything it changes is not still present in v1.
|
||||||
|
- [Add reorder field](https://github.com/kubernetes-sigs/kustomize/issues/3913). Default should be FIFO and legacy should also be supported (could add alphabetic and custom sort support eventually). Replaces -reorder flag.
|
||||||
|
- [Reconcile openapi and crds field](https://github.com/kubernetes-sigs/kustomize/issues/3944)
|
||||||
|
- [Consider deprecating configurations field](https://github.com/kubernetes-sigs/kustomize/issues/3945) (old, pre-plugin, pre-openapi global configuration)
|
||||||
|
- [Add a field to enable the managedby label](https://github.com/kubernetes-sigs/kustomize/issues/4047)
|
||||||
|
|
||||||
|
Second priority:
|
||||||
|
|
||||||
|
- Improve contributor documentation
|
||||||
|
- [Instructions to upgrade kustomize-in-kubectl](https://github.com/kubernetes-sigs/kustomize/issues/3951)
|
||||||
|
|
||||||
|
Also very valuable to the project:
|
||||||
|
|
||||||
|
- [Improve the release process](https://github.com/kubernetes-sigs/kustomize/issues/3952) to support regular biweekly releases [PROJECT](https://github.com/kubernetes-sigs/kustomize/projects/7)
|
||||||
|
- Release sigs.k8s.io/kustomize/api v1.0.0 [PROJECT](https://github.com/kubernetes-sigs/kustomize/projects/5)
|
||||||
|
- [Reduce the public surface of the API module](https://github.com/kubernetes-sigs/kustomize/issues/3942)
|
||||||
|
- [Vendor all transitive deps](https://github.com/kubernetes-sigs/kustomize/issues/3706). Since kustomize is in kubectl, we must do as kubectl does to manage deps, exposing new transitive deps in code review.
|
||||||
|
- Project administration
|
||||||
|
- [Rename master branch to main](https://github.com/kubernetes-sigs/kustomize/issues/3954)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Objective: Improve end-user experience
|
||||||
|
|
||||||
|
**_WHO: End user that wants kustomize build artifacts (binaries, containers)._**
|
||||||
|
|
||||||
|
Top priorities:
|
||||||
|
|
||||||
|
- Bug fixes:
|
||||||
|
- Fix bugs in basic anchor support: [issue query](https://github.com/kubernetes-sigs/kustomize/issues?q=is%3Aopen+is%3Aissue+label%3Aarea%2Fanchors)
|
||||||
|
- integer keys support: [#3446](https://github.com/kubernetes-sigs/kustomize/issues/3446)
|
||||||
|
- kyaml not respecting \`$patch replace|retainKeys\`: [#2037](https://github.com/kubernetes-sigs/kustomize/issues/2037)
|
||||||
|
- kustomize removing quotes from namespace field values: [#4146](https://github.com/kubernetes-sigs/kustomize/issues/4146)
|
||||||
|
- Kustomize doesn’t support metadata.generateName: [#641](https://github.com/kubernetes-sigs/kustomize/issues/641)
|
||||||
|
- Send kustomize CLI version number into kubectl ([kubectl issue](https://github.com/kubernetes/kubectl/issues/797) / [kustomize issue](https://github.com/kubernetes-sigs/kustomize/issues/1424))
|
||||||
|
- Kustomize performance investigations/improvements [PROJECT](https://github.com/kubernetes-sigs/kustomize/projects/13)
|
||||||
|
- [Support generic resource references in name reference tracking](https://github.com/kubernetes-sigs/kustomize/issues/3418)
|
||||||
|
- [KEP 4267: retain the resource origin and transformer data in annotations](https://github.com/kubernetes-sigs/kustomize/pull/4267)
|
||||||
|
|
||||||
|
Secondary priorities:
|
||||||
|
|
||||||
|
- kustomize cli v5 ([PROJECT](https://github.com/kubernetes-sigs/kustomize/projects/14))
|
||||||
|
- [Drop the --reorder flag](https://github.com/kubernetes-sigs/kustomize/issues/3947)
|
||||||
|
- [Graduate cfg read-only commands out of alpha](https://github.com/kubernetes-sigs/kustomize/issues/4090).
|
||||||
|
- [Drop the –enable-managedby-label](https://github.com/kubernetes-sigs/kustomize/issues/4047)
|
||||||
|
- Drop old plugin-related fields in favor of [the Catalog-style fields](https://github.com/kubernetes/enhancements/tree/master/keps/sig-cli/2906-kustomize-function-catalog).
|
||||||
|
- [Drop the helm flags](https://github.com/kubernetes-sigs/kustomize/issues/4401)
|
||||||
|
- [Confusion around namespace replacement](https://github.com/kubernetes-sigs/kustomize/issues/880).
|
||||||
|
|
||||||
|
Also very valuable to the project:
|
||||||
|
|
||||||
|
- [Overinclusion of root directory error in error messages](https://github.com/kubernetes-sigs/kustomize/issues/4348)
|
||||||
|
- [Add kustomize localize command](https://github.com/kubernetes-sigs/kustomize/issues/3980)
|
||||||
|
- [Fix Windows support in test suite](https://github.com/kubernetes-sigs/kustomize/issues/4001)
|
||||||
|
- Improve end-user documentation [PROJECT](https://github.com/kubernetes-sigs/kustomize/projects/9)
|
||||||
|
|
||||||
|
|
||||||
|
## Objective: Improve extension experience
|
||||||
|
|
||||||
|
**_WHO: Plugin developers: end users who extend kustomize, but don’t think about internals._**
|
||||||
|
|
||||||
|
This objective is described in detail in the [Kustomize Plugin Graduation KEP](https://github.com/kubernetes/enhancements/tree/master/keps/sig-cli/2953-kustomize-plugin-graduation) / [PROJECT](https://github.com/kubernetes-sigs/kustomize/projects/15) .
|
||||||
|
|
||||||
|
Top priorities:
|
||||||
|
|
||||||
|
- Fix core usability issues with KRM Function extensions:
|
||||||
|
- [Better errors for function config failures](https://github.com/kubernetes-sigs/kustomize/issues/4398)
|
||||||
|
- [Container KRM Mounts are not mounting via function parameters](https://github.com/kubernetes-sigs/kustomize/issues/4290)
|
||||||
|
- [Resolution of local file references in extensions transformer configuration](https://github.com/kubernetes-sigs/kustomize/issues/4154)
|
||||||
|
- [Do not silently ignore plugins when config has typo](https://github.com/kubernetes-sigs/kustomize/issues/4399)
|
||||||
|
- [KRM Exec Function can't locate executable when referencing a base](https://github.com/kubernetes-sigs/kustomize/issues/4347)
|
||||||
|
- Once core usability issues are fixed, [deprecate legacy exec and Go plugin support](https://github.com/kubernetes/enhancements/tree/master/keps/sig-cli/2953-kustomize-plugin-graduation)
|
||||||
|
- [Catalog KEP](https://github.com/kubernetes/enhancements/tree/master/keps/sig-cli/2906-kustomize-function-catalog)
|
||||||
|
|
||||||
|
Secondary priorities:
|
||||||
|
|
||||||
|
- [Remove Starlark support](https://github.com/kubernetes-sigs/kustomize/issues/4349)
|
||||||
|
- [Composition KEP](https://github.com/kubernetes/enhancements/pull/2300). The implementation is complete in [#4223](https://github.com/kubernetes-sigs/kustomize/pull/4323), but depends on:
|
||||||
|
- [Convert resources and components to be backed by a reusable generator](https://github.com/kubernetes-sigs/kustomize/issues/4402)
|
||||||
|
- [Enable explicitly invoked transformers to use default fieldSpecs](https://github.com/kubernetes-sigs/kustomize/issues/4404)
|
||||||
|
- [Enable built-in generators to be used in the transformers field ](https://github.com/kubernetes-sigs/kustomize/issues/4403)
|
||||||
|
|
||||||
|
|
||||||
|
Also very valuable to the project:
|
||||||
|
|
||||||
|
- [Improve docs for kyaml libraries](https://github.com/kubernetes-sigs/kustomize/issues/3950), especially by adding examples.
|
||||||
|
- [Create a reserved field for plugin runtime information](https://github.com/kubernetes-sigs/kustomize/issues/4405)
|
||||||
|
- [Develop new standard process for implementing builtin transformers](https://github.com/kubernetes-sigs/kustomize/issues/4400)
|
||||||
14
api/Makefile
Normal file
14
api/Makefile
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
# Copyright 2022 The Kubernetes Authors.
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
include ../Makefile-modules.mk
|
||||||
|
|
||||||
|
test:
|
||||||
|
go test -v -timeout 45m -cover ./... -ldflags "-X sigs.k8s.io/kustomize/api/provenance.version=v444.333.222"
|
||||||
|
cd krusty/openapitests; OPENAPI_TEST=true go test -v -timeout 45m -p 1 -cover ./...
|
||||||
|
|
||||||
|
build:
|
||||||
|
go build -ldflags "-X sigs.k8s.io/kustomize/api/provenance.version=v444.333.222" ./...
|
||||||
|
|
||||||
|
generate: $(MYGOBIN)/k8scopy $(MYGOBIN)/stringer
|
||||||
|
go generate ./...
|
||||||
@@ -285,7 +285,7 @@ spec:
|
|||||||
t.Run(tn, func(t *testing.T) {
|
t.Run(tn, func(t *testing.T) {
|
||||||
filter := tc.filter
|
filter := tc.filter
|
||||||
filter.WithMutationTracker(tc.setEntryCallback)
|
filter.WithMutationTracker(tc.setEntryCallback)
|
||||||
filter.FsSlice = append(annosFs, tc.fsslice...)
|
filter.FsSlice = append(annosFs, tc.fsslice...) //nolint:gocritic
|
||||||
if !assert.Equal(t,
|
if !assert.Equal(t,
|
||||||
strings.TrimSpace(tc.expectedOutput),
|
strings.TrimSpace(tc.expectedOutput),
|
||||||
strings.TrimSpace(filtertest_test.RunFilter(t, tc.input, filter))) {
|
strings.TrimSpace(filtertest_test.RunFilter(t, tc.input, filter))) {
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// Copyright 2022 The Kubernetes Authors.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
package filters
|
package filters
|
||||||
|
|
||||||
// Package filters collects various implementations
|
// Package filters collects various implementations
|
||||||
|
|||||||
@@ -8,10 +8,10 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"sigs.k8s.io/kustomize/api/filters/filtersutil"
|
"sigs.k8s.io/kustomize/api/filters/filtersutil"
|
||||||
"sigs.k8s.io/kustomize/api/internal/utils"
|
|
||||||
"sigs.k8s.io/kustomize/api/types"
|
"sigs.k8s.io/kustomize/api/types"
|
||||||
"sigs.k8s.io/kustomize/kyaml/errors"
|
"sigs.k8s.io/kustomize/kyaml/errors"
|
||||||
"sigs.k8s.io/kustomize/kyaml/resid"
|
"sigs.k8s.io/kustomize/kyaml/resid"
|
||||||
|
"sigs.k8s.io/kustomize/kyaml/utils"
|
||||||
"sigs.k8s.io/kustomize/kyaml/yaml"
|
"sigs.k8s.io/kustomize/kyaml/yaml"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// Copyright 2022 The Kubernetes Authors.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
package filtersutil
|
package filtersutil
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -21,9 +24,6 @@ func SetEntry(key, value, tag string) SetFn {
|
|||||||
Value: value,
|
Value: value,
|
||||||
Tag: tag,
|
Tag: tag,
|
||||||
}
|
}
|
||||||
if tag == yaml.NodeTagString && yaml.IsYaml1_1NonString(n) {
|
|
||||||
n.Style = yaml.DoubleQuotedStyle
|
|
||||||
}
|
|
||||||
return func(node *yaml.RNode) error {
|
return func(node *yaml.RNode) error {
|
||||||
return node.PipeE(yaml.FieldSetter{
|
return node.PipeE(yaml.FieldSetter{
|
||||||
Name: key,
|
Name: key,
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// Copyright 2022 The Kubernetes Authors.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
// Package gkesagenerator contains a kio.Filter that that generates a
|
// Package gkesagenerator contains a kio.Filter that that generates a
|
||||||
// iampolicy-related resources for a given cloud provider
|
// iampolicy-related resources for a given cloud provider
|
||||||
package iampolicygenerator
|
package iampolicygenerator
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ metadata:
|
|||||||
f.IAMPolicyGenerator.KubernetesService.Name)
|
f.IAMPolicyGenerator.KubernetesService.Name)
|
||||||
|
|
||||||
if f.IAMPolicyGenerator.Namespace != "" {
|
if f.IAMPolicyGenerator.Namespace != "" {
|
||||||
input = input + fmt.Sprintf("\n namespace: %s", f.IAMPolicyGenerator.Namespace)
|
input += fmt.Sprintf("\n namespace: %s", f.IAMPolicyGenerator.Namespace)
|
||||||
}
|
}
|
||||||
|
|
||||||
sa, err := yaml.Parse(input)
|
sa, err := yaml.Parse(input)
|
||||||
|
|||||||
@@ -750,6 +750,135 @@ spec:
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
"image with tag and digest new name": {
|
||||||
|
input: `
|
||||||
|
apiVersion: example.com/v1
|
||||||
|
kind: Foo
|
||||||
|
metadata:
|
||||||
|
name: instance
|
||||||
|
spec:
|
||||||
|
image: nginx:1.2.1@sha256:46d5b90a7f4e9996351ad893a26bcbd27216676ad4d5316088ce351fb2c2c3dd
|
||||||
|
`,
|
||||||
|
expectedOutput: `
|
||||||
|
apiVersion: example.com/v1
|
||||||
|
kind: Foo
|
||||||
|
metadata:
|
||||||
|
name: instance
|
||||||
|
spec:
|
||||||
|
image: apache:1.2.1@sha256:46d5b90a7f4e9996351ad893a26bcbd27216676ad4d5316088ce351fb2c2c3dd
|
||||||
|
`,
|
||||||
|
filter: Filter{
|
||||||
|
ImageTag: types.Image{
|
||||||
|
Name: "nginx",
|
||||||
|
NewName: "apache",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
fsSlice: []types.FieldSpec{
|
||||||
|
{
|
||||||
|
Path: "spec/image",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"image with tag and digest new name new tag": {
|
||||||
|
input: `
|
||||||
|
apiVersion: example.com/v1
|
||||||
|
kind: Foo
|
||||||
|
metadata:
|
||||||
|
name: instance
|
||||||
|
spec:
|
||||||
|
image: nginx:1.2.1@sha256:46d5b90a7f4e9996351ad893a26bcbd27216676ad4d5316088ce351fb2c2c3dd
|
||||||
|
`,
|
||||||
|
expectedOutput: `
|
||||||
|
apiVersion: example.com/v1
|
||||||
|
kind: Foo
|
||||||
|
metadata:
|
||||||
|
name: instance
|
||||||
|
spec:
|
||||||
|
image: apache:1.3.0
|
||||||
|
`,
|
||||||
|
filter: Filter{
|
||||||
|
ImageTag: types.Image{
|
||||||
|
Name: "nginx",
|
||||||
|
NewName: "apache",
|
||||||
|
NewTag: "1.3.0",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
fsSlice: []types.FieldSpec{
|
||||||
|
{
|
||||||
|
Path: "spec/image",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"image with tag and digest new name new tag and digest": {
|
||||||
|
input: `
|
||||||
|
apiVersion: example.com/v1
|
||||||
|
kind: Foo
|
||||||
|
metadata:
|
||||||
|
name: instance
|
||||||
|
spec:
|
||||||
|
image: nginx:1.2.1@sha256:46d5b90a7f4e9996351ad893a26bcbd27216676ad4d5316088ce351fb2c2c3dd
|
||||||
|
`,
|
||||||
|
expectedOutput: `
|
||||||
|
apiVersion: example.com/v1
|
||||||
|
kind: Foo
|
||||||
|
metadata:
|
||||||
|
name: instance
|
||||||
|
spec:
|
||||||
|
image: apache:1.3.0@sha256:xyz
|
||||||
|
`,
|
||||||
|
filter: Filter{
|
||||||
|
ImageTag: types.Image{
|
||||||
|
Name: "nginx",
|
||||||
|
NewName: "apache",
|
||||||
|
NewTag: "1.3.0",
|
||||||
|
Digest: "sha256:xyz",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
fsSlice: []types.FieldSpec{
|
||||||
|
{
|
||||||
|
Path: "spec/image",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"updateimagesuffix": {
|
||||||
|
input: `
|
||||||
|
group: apps
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: deploysuffix
|
||||||
|
spec:
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- image: redis:6.2.6
|
||||||
|
name: redis
|
||||||
|
`,
|
||||||
|
expectedOutput: `
|
||||||
|
group: apps
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: deploysuffix
|
||||||
|
spec:
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- image: redis:6.2.6-alpine
|
||||||
|
name: redis
|
||||||
|
`,
|
||||||
|
filter: Filter{
|
||||||
|
ImageTag: types.Image{
|
||||||
|
Name: "redis",
|
||||||
|
TagSuffix: "-alpine",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
fsSlice: []types.FieldSpec{
|
||||||
|
{
|
||||||
|
Path: "spec/template/spec/containers[]/image",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for tn, tc := range testCases {
|
for tn, tc := range testCases {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ package imagetag
|
|||||||
import (
|
import (
|
||||||
"sigs.k8s.io/kustomize/api/internal/utils"
|
"sigs.k8s.io/kustomize/api/internal/utils"
|
||||||
"sigs.k8s.io/kustomize/api/types"
|
"sigs.k8s.io/kustomize/api/types"
|
||||||
|
"sigs.k8s.io/kustomize/kyaml/errors"
|
||||||
"sigs.k8s.io/kustomize/kyaml/kio"
|
"sigs.k8s.io/kustomize/kyaml/kio"
|
||||||
"sigs.k8s.io/kustomize/kyaml/yaml"
|
"sigs.k8s.io/kustomize/kyaml/yaml"
|
||||||
)
|
)
|
||||||
@@ -81,9 +82,7 @@ func (f findFieldsFilter) walk(node *yaml.RNode) error {
|
|||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
case yaml.SequenceNode:
|
case yaml.SequenceNode:
|
||||||
return node.VisitElements(func(n *yaml.RNode) error {
|
return errors.Wrap(node.VisitElements(f.walk))
|
||||||
return f.walk(n)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ package imagetag
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"sigs.k8s.io/kustomize/api/filters/filtersutil"
|
"sigs.k8s.io/kustomize/api/filters/filtersutil"
|
||||||
|
|
||||||
"sigs.k8s.io/kustomize/api/image"
|
"sigs.k8s.io/kustomize/api/image"
|
||||||
"sigs.k8s.io/kustomize/api/types"
|
"sigs.k8s.io/kustomize/api/types"
|
||||||
"sigs.k8s.io/kustomize/kyaml/yaml"
|
"sigs.k8s.io/kustomize/kyaml/yaml"
|
||||||
@@ -30,18 +31,36 @@ func (u imageTagUpdater) SetImageValue(rn *yaml.RNode) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
name, tag := image.Split(value)
|
name, tag, digest := image.Split(value)
|
||||||
if u.ImageTag.NewName != "" {
|
if u.ImageTag.NewName != "" {
|
||||||
name = u.ImageTag.NewName
|
name = u.ImageTag.NewName
|
||||||
}
|
}
|
||||||
if u.ImageTag.NewTag != "" {
|
|
||||||
tag = ":" + u.ImageTag.NewTag
|
// overriding tag or digest will replace both original tag and digest values
|
||||||
}
|
switch {
|
||||||
if u.ImageTag.Digest != "" {
|
case u.ImageTag.NewTag != "" && u.ImageTag.Digest != "":
|
||||||
tag = "@" + u.ImageTag.Digest
|
tag = u.ImageTag.NewTag
|
||||||
|
digest = u.ImageTag.Digest
|
||||||
|
case u.ImageTag.NewTag != "":
|
||||||
|
tag = u.ImageTag.NewTag
|
||||||
|
digest = ""
|
||||||
|
case u.ImageTag.Digest != "":
|
||||||
|
tag = ""
|
||||||
|
digest = u.ImageTag.Digest
|
||||||
|
case u.ImageTag.TagSuffix != "":
|
||||||
|
tag += u.ImageTag.TagSuffix
|
||||||
|
digest = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
return u.trackableSetter.SetScalar(name + tag)(rn)
|
// build final image name
|
||||||
|
if tag != "" {
|
||||||
|
name += ":" + tag
|
||||||
|
}
|
||||||
|
if digest != "" {
|
||||||
|
name += "@" + digest
|
||||||
|
}
|
||||||
|
|
||||||
|
return u.trackableSetter.SetScalar(name)(rn)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u imageTagUpdater) Filter(rn *yaml.RNode) (*yaml.RNode, error) {
|
func (u imageTagUpdater) Filter(rn *yaml.RNode) (*yaml.RNode, error) {
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// Copyright 2022 The Kubernetes Authors.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
// Package nameref contains a kio.Filter implementation of the kustomize
|
// Package nameref contains a kio.Filter implementation of the kustomize
|
||||||
// name reference transformer.
|
// name reference transformer.
|
||||||
package nameref
|
package nameref
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// Copyright 2022 The Kubernetes Authors.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
package nameref
|
package nameref
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// Copyright 2022 The Kubernetes Authors.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
package nameref
|
package nameref
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// Copyright 2022 The Kubernetes Authors.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
package nameref
|
package nameref
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// Copyright 2022 The Kubernetes Authors.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
package nameref
|
package nameref
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ func (ns Filter) run(node *yaml.RNode) (*yaml.RNode, error) {
|
|||||||
// transformations based on data -- :)
|
// transformations based on data -- :)
|
||||||
err := node.PipeE(fsslice.Filter{
|
err := node.PipeE(fsslice.Filter{
|
||||||
FsSlice: ns.FsSlice,
|
FsSlice: ns.FsSlice,
|
||||||
SetValue: ns.trackableSetter.SetScalar(ns.Namespace),
|
SetValue: ns.trackableSetter.SetEntry("", ns.Namespace, yaml.NodeTagString),
|
||||||
CreateKind: yaml.ScalarNode, // Namespace is a ScalarNode
|
CreateKind: yaml.ScalarNode, // Namespace is a ScalarNode
|
||||||
CreateTag: yaml.NodeTagString,
|
CreateTag: yaml.NodeTagString,
|
||||||
})
|
})
|
||||||
@@ -85,7 +85,7 @@ func (ns Filter) metaNamespaceHack(obj *yaml.RNode, gvk resid.Gvk) error {
|
|||||||
FsSlice: []types.FieldSpec{
|
FsSlice: []types.FieldSpec{
|
||||||
{Path: types.MetadataNamespacePath, CreateIfNotPresent: true},
|
{Path: types.MetadataNamespacePath, CreateIfNotPresent: true},
|
||||||
},
|
},
|
||||||
SetValue: ns.trackableSetter.SetScalar(ns.Namespace),
|
SetValue: ns.trackableSetter.SetEntry("", ns.Namespace, yaml.NodeTagString),
|
||||||
CreateKind: yaml.ScalarNode, // Namespace is a ScalarNode
|
CreateKind: yaml.ScalarNode, // Namespace is a ScalarNode
|
||||||
}
|
}
|
||||||
_, err := f.Filter(obj)
|
_, err := f.Filter(obj)
|
||||||
@@ -138,8 +138,7 @@ func (ns Filter) roleBindingHack(obj *yaml.RNode, gvk resid.Gvk) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return ns.trackableSetter.SetScalar(ns.Namespace)(node)
|
return ns.trackableSetter.SetEntry("", ns.Namespace, yaml.NodeTagString)(node)
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -332,26 +332,60 @@ a:
|
|||||||
expectedSetValueArgs: []filtertest_test.SetValueArg{
|
expectedSetValueArgs: []filtertest_test.SetValueArg{
|
||||||
{
|
{
|
||||||
Value: "bar",
|
Value: "bar",
|
||||||
|
Tag: "!!str",
|
||||||
NodePath: []string{"metadata", "namespace"},
|
NodePath: []string{"metadata", "namespace"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Value: "bar",
|
Value: "bar",
|
||||||
|
Tag: "!!str",
|
||||||
NodePath: []string{"a", "b", "c"},
|
NodePath: []string{"a", "b", "c"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Value: "bar",
|
Value: "bar",
|
||||||
|
Tag: "!!str",
|
||||||
NodePath: []string{"metadata", "namespace"},
|
NodePath: []string{"metadata", "namespace"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Value: "bar",
|
Value: "bar",
|
||||||
|
Tag: "!!str",
|
||||||
NodePath: []string{"namespace"},
|
NodePath: []string{"namespace"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Value: "bar",
|
Value: "bar",
|
||||||
|
Tag: "!!str",
|
||||||
NodePath: []string{"a", "b", "c"},
|
NodePath: []string{"a", "b", "c"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
name: "numeric",
|
||||||
|
input: `
|
||||||
|
apiVersion: example.com/v1
|
||||||
|
kind: Foo
|
||||||
|
metadata:
|
||||||
|
name: instance
|
||||||
|
---
|
||||||
|
apiVersion: example.com/v1
|
||||||
|
kind: Bar
|
||||||
|
metadata:
|
||||||
|
name: instance
|
||||||
|
`,
|
||||||
|
expected: `
|
||||||
|
apiVersion: example.com/v1
|
||||||
|
kind: Foo
|
||||||
|
metadata:
|
||||||
|
name: instance
|
||||||
|
namespace: "01234"
|
||||||
|
---
|
||||||
|
apiVersion: example.com/v1
|
||||||
|
kind: Bar
|
||||||
|
metadata:
|
||||||
|
name: instance
|
||||||
|
namespace: "01234"
|
||||||
|
`,
|
||||||
|
filter: namespace.Filter{Namespace: "01234"},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
type TestCase struct {
|
type TestCase struct {
|
||||||
@@ -372,7 +406,7 @@ func TestNamespace_Filter(t *testing.T) {
|
|||||||
test := tests[i]
|
test := tests[i]
|
||||||
test.filter.WithMutationTracker(test.mutationTracker)
|
test.filter.WithMutationTracker(test.mutationTracker)
|
||||||
t.Run(test.name, func(t *testing.T) {
|
t.Run(test.name, func(t *testing.T) {
|
||||||
test.filter.FsSlice = append(config.NameSpace, test.fsslice...)
|
test.filter.FsSlice = append(config.NameSpace, test.fsslice...) //nolint:gocritic
|
||||||
if !assert.Equal(t,
|
if !assert.Equal(t,
|
||||||
strings.TrimSpace(test.expected),
|
strings.TrimSpace(test.expected),
|
||||||
strings.TrimSpace(
|
strings.TrimSpace(
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// Copyright 2022 The Kubernetes Authors.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
package patchstrategicmerge
|
package patchstrategicmerge
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// Copyright 2022 The Kubernetes Authors.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
// Package refvar contains a kio.Filter implementation of the kustomize
|
// Package refvar contains a kio.Filter implementation of the kustomize
|
||||||
// refvar transformer (find and replace $(FOO) style variables in strings).
|
// refvar transformer (find and replace $(FOO) style variables in strings).
|
||||||
package refvar
|
package refvar
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// Copyright 2022 The Kubernetes Authors.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
package refvar
|
package refvar
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// Copyright 2022 The Kubernetes Authors.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
package refvar_test
|
package refvar_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -17,7 +20,6 @@ var makeMf = func(theMap map[string]interface{}) MappingFunc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestFilter(t *testing.T) {
|
func TestFilter(t *testing.T) {
|
||||||
|
|
||||||
testCases := map[string]struct {
|
testCases := map[string]struct {
|
||||||
input string
|
input string
|
||||||
expected string
|
expected string
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// Copyright 2022 The Kubernetes Authors.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
// Package replacement contains a kio.Filter implementation of the kustomize
|
// Package replacement contains a kio.Filter implementation of the kustomize
|
||||||
// replacement transformer (accepts sources and looks for targets to replace
|
// replacement transformer (accepts sources and looks for targets to replace
|
||||||
// their values with values from the sources).
|
// their values with values from the sources).
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
package replacement
|
package replacement
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@@ -11,6 +12,7 @@ import (
|
|||||||
"sigs.k8s.io/kustomize/api/resource"
|
"sigs.k8s.io/kustomize/api/resource"
|
||||||
"sigs.k8s.io/kustomize/api/types"
|
"sigs.k8s.io/kustomize/api/types"
|
||||||
"sigs.k8s.io/kustomize/kyaml/resid"
|
"sigs.k8s.io/kustomize/kyaml/resid"
|
||||||
|
kyaml_utils "sigs.k8s.io/kustomize/kyaml/utils"
|
||||||
"sigs.k8s.io/kustomize/kyaml/yaml"
|
"sigs.k8s.io/kustomize/kyaml/yaml"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -20,11 +22,11 @@ type Filter struct {
|
|||||||
|
|
||||||
// Filter replaces values of targets with values from sources
|
// Filter replaces values of targets with values from sources
|
||||||
func (f Filter) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) {
|
func (f Filter) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) {
|
||||||
for _, r := range f.Replacements {
|
for i, r := range f.Replacements {
|
||||||
if r.Source == nil || r.Targets == nil {
|
if r.Source == nil || r.Targets == nil {
|
||||||
return nil, fmt.Errorf("replacements must specify a source and at least one target")
|
return nil, fmt.Errorf("replacements must specify a source and at least one target")
|
||||||
}
|
}
|
||||||
value, err := getReplacement(nodes, &r)
|
value, err := getReplacement(nodes, &f.Replacements[i])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -60,8 +62,8 @@ func applyReplacement(nodes []*yaml.RNode, value *yaml.RNode, targets []*types.T
|
|||||||
}
|
}
|
||||||
|
|
||||||
// filter targets by matching resource IDs
|
// filter targets by matching resource IDs
|
||||||
for _, id := range ids {
|
for i, id := range ids {
|
||||||
if id.IsSelectedBy(t.Select.ResId) && !rejectId(t.Reject, &id) {
|
if id.IsSelectedBy(t.Select.ResId) && !rejectId(t.Reject, &ids[i]) {
|
||||||
err := applyToNode(n, value, t)
|
err := applyToNode(n, value, t)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -113,19 +115,27 @@ func rejectId(rejects []*types.Selector, id *resid.ResId) bool {
|
|||||||
|
|
||||||
func applyToNode(node *yaml.RNode, value *yaml.RNode, target *types.TargetSelector) error {
|
func applyToNode(node *yaml.RNode, value *yaml.RNode, target *types.TargetSelector) error {
|
||||||
for _, fp := range target.FieldPaths {
|
for _, fp := range target.FieldPaths {
|
||||||
fieldPath := utils.SmarterPathSplitter(fp, ".")
|
fieldPath := kyaml_utils.SmarterPathSplitter(fp, ".")
|
||||||
var t *yaml.RNode
|
var t *yaml.RNode
|
||||||
var err error
|
var err error
|
||||||
if target.Options != nil && target.Options.Create {
|
if target.Options != nil && target.Options.Create {
|
||||||
|
// create option is not supported in a wildcard matching.
|
||||||
|
// Because, PathMatcher is not supported create option.
|
||||||
|
// So, if create option is set, we fallback to PathGetter.
|
||||||
|
for _, f := range fieldPath {
|
||||||
|
if f == "*" {
|
||||||
|
return errors.New("cannot support create option in a multi-value target") //nolint:goerr113
|
||||||
|
}
|
||||||
|
}
|
||||||
t, err = node.Pipe(yaml.LookupCreate(value.YNode().Kind, fieldPath...))
|
t, err = node.Pipe(yaml.LookupCreate(value.YNode().Kind, fieldPath...))
|
||||||
} else {
|
} else {
|
||||||
t, err = node.Pipe(yaml.Lookup(fieldPath...))
|
t, err = node.Pipe(&yaml.PathMatcher{Path: fieldPath})
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if t != nil {
|
if t != nil {
|
||||||
if err = setTargetValue(target.Options, t, value); err != nil {
|
if err = applyToOneNode(target.Options, t, value); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -133,6 +143,24 @@ func applyToNode(node *yaml.RNode, value *yaml.RNode, target *types.TargetSelect
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func applyToOneNode(options *types.FieldOptions, t *yaml.RNode, value *yaml.RNode) error {
|
||||||
|
if len(t.YNode().Content) == 0 {
|
||||||
|
if err := setTargetValue(options, t, value); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, scalarNode := range t.YNode().Content {
|
||||||
|
rn := yaml.NewRNode(scalarNode)
|
||||||
|
if err := setTargetValue(options, rn, value); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func setTargetValue(options *types.FieldOptions, t *yaml.RNode, value *yaml.RNode) error {
|
func setTargetValue(options *types.FieldOptions, t *yaml.RNode, value *yaml.RNode) error {
|
||||||
value = value.Copy()
|
value = value.Copy()
|
||||||
if options != nil && options.Delimiter != "" {
|
if options != nil && options.Delimiter != "" {
|
||||||
@@ -152,7 +180,14 @@ func setTargetValue(options *types.FieldOptions, t *yaml.RNode, value *yaml.RNod
|
|||||||
}
|
}
|
||||||
value.YNode().Value = strings.Join(tv, options.Delimiter)
|
value.YNode().Value = strings.Join(tv, options.Delimiter)
|
||||||
}
|
}
|
||||||
t.SetYNode(value.YNode())
|
|
||||||
|
if t.YNode().Kind == yaml.ScalarNode {
|
||||||
|
// For scalar, only copy the value (leave any type intact to auto-convert int->string or string->int)
|
||||||
|
t.YNode().Value = value.YNode().Value
|
||||||
|
} else {
|
||||||
|
t.SetYNode(value.YNode())
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -165,7 +200,7 @@ func getReplacement(nodes []*yaml.RNode, r *types.Replacement) (*yaml.RNode, err
|
|||||||
if r.Source.FieldPath == "" {
|
if r.Source.FieldPath == "" {
|
||||||
r.Source.FieldPath = types.DefaultReplacementFieldPath
|
r.Source.FieldPath = types.DefaultReplacementFieldPath
|
||||||
}
|
}
|
||||||
fieldPath := utils.SmarterPathSplitter(r.Source.FieldPath, ".")
|
fieldPath := kyaml_utils.SmarterPathSplitter(r.Source.FieldPath, ".")
|
||||||
|
|
||||||
rn, err := source.Pipe(yaml.Lookup(fieldPath...))
|
rn, err := source.Pipe(yaml.Lookup(fieldPath...))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ spec:
|
|||||||
- select:
|
- select:
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
name: deploy
|
name: deploy
|
||||||
fieldPaths:
|
fieldPaths:
|
||||||
- spec.template.spec.containers.1.image
|
- spec.template.spec.containers.1.image
|
||||||
`,
|
`,
|
||||||
expected: `apiVersion: v1
|
expected: `apiVersion: v1
|
||||||
@@ -95,7 +95,7 @@ spec:
|
|||||||
targets:
|
targets:
|
||||||
- select:
|
- select:
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
fieldPaths:
|
fieldPaths:
|
||||||
- spec.template.spec.containers
|
- spec.template.spec.containers
|
||||||
`,
|
`,
|
||||||
expected: `apiVersion: v1
|
expected: `apiVersion: v1
|
||||||
@@ -205,13 +205,13 @@ spec:
|
|||||||
command: ["printenv"]
|
command: ["printenv"]
|
||||||
args:
|
args:
|
||||||
- example.com
|
- example.com
|
||||||
- 8080
|
- "8080"
|
||||||
- name: busybox
|
- name: busybox
|
||||||
image: busybox:latest
|
image: busybox:latest
|
||||||
args:
|
args:
|
||||||
- echo
|
- echo
|
||||||
- example.com
|
- example.com
|
||||||
- 8080
|
- "8080"
|
||||||
---
|
---
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: ConfigMap
|
kind: ConfigMap
|
||||||
@@ -328,7 +328,7 @@ spec:
|
|||||||
- select:
|
- select:
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
name: deploy1
|
name: deploy1
|
||||||
fieldPaths:
|
fieldPaths:
|
||||||
- spec.template.spec.containers.[name=postgresdb].image
|
- spec.template.spec.containers.[name=postgresdb].image
|
||||||
`,
|
`,
|
||||||
expected: `apiVersion: v1
|
expected: `apiVersion: v1
|
||||||
@@ -405,7 +405,7 @@ spec:
|
|||||||
targets:
|
targets:
|
||||||
- select:
|
- select:
|
||||||
version: v3
|
version: v3
|
||||||
fieldPaths:
|
fieldPaths:
|
||||||
- spec.template.spec.containers.1.image
|
- spec.template.spec.containers.1.image
|
||||||
`,
|
`,
|
||||||
expected: `apiVersion: my-group-1/v1
|
expected: `apiVersion: my-group-1/v1
|
||||||
@@ -492,7 +492,7 @@ spec:
|
|||||||
targets:
|
targets:
|
||||||
- select:
|
- select:
|
||||||
name: my-name-2
|
name: my-name-2
|
||||||
fieldPaths:
|
fieldPaths:
|
||||||
- spec.template.spec.containers.1.image
|
- spec.template.spec.containers.1.image
|
||||||
`,
|
`,
|
||||||
expected: `spec:
|
expected: `spec:
|
||||||
@@ -582,7 +582,7 @@ spec:
|
|||||||
reject:
|
reject:
|
||||||
- name: deploy2
|
- name: deploy2
|
||||||
- name: deploy3
|
- name: deploy3
|
||||||
fieldPaths:
|
fieldPaths:
|
||||||
- spec.template.spec.containers.1.image
|
- spec.template.spec.containers.1.image
|
||||||
`,
|
`,
|
||||||
expected: `apiVersion: v1
|
expected: `apiVersion: v1
|
||||||
@@ -662,7 +662,7 @@ spec:
|
|||||||
reject:
|
reject:
|
||||||
- kind: Deployment
|
- kind: Deployment
|
||||||
name: my-name
|
name: my-name
|
||||||
fieldPaths:
|
fieldPaths:
|
||||||
- spec.template.spec.containers.1.image
|
- spec.template.spec.containers.1.image
|
||||||
`,
|
`,
|
||||||
expected: `apiVersion: v1
|
expected: `apiVersion: v1
|
||||||
@@ -731,7 +731,7 @@ spec:
|
|||||||
reject:
|
reject:
|
||||||
- kind: Deployment
|
- kind: Deployment
|
||||||
- name: my-name
|
- name: my-name
|
||||||
fieldPaths:
|
fieldPaths:
|
||||||
- spec.template.spec.containers.1.image
|
- spec.template.spec.containers.1.image
|
||||||
`,
|
`,
|
||||||
expected: `apiVersion: v1
|
expected: `apiVersion: v1
|
||||||
@@ -799,7 +799,7 @@ spec:
|
|||||||
- select:
|
- select:
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
name: deploy1
|
name: deploy1
|
||||||
fieldPaths:
|
fieldPaths:
|
||||||
- spec.template.spec.containers.1.image
|
- spec.template.spec.containers.1.image
|
||||||
options:
|
options:
|
||||||
delimiter: ':'
|
delimiter: ':'
|
||||||
@@ -872,7 +872,7 @@ spec:
|
|||||||
- select:
|
- select:
|
||||||
kind: Pod
|
kind: Pod
|
||||||
name: pod2
|
name: pod2
|
||||||
fieldPaths:
|
fieldPaths:
|
||||||
- spec.volumes.0.projected.sources.0.configMap.items.0.path
|
- spec.volumes.0.projected.sources.0.configMap.items.0.path
|
||||||
options:
|
options:
|
||||||
delimiter: '/'
|
delimiter: '/'
|
||||||
@@ -948,7 +948,7 @@ spec:
|
|||||||
- select:
|
- select:
|
||||||
kind: Pod
|
kind: Pod
|
||||||
name: pod1
|
name: pod1
|
||||||
fieldPaths:
|
fieldPaths:
|
||||||
- spec.volumes.0.projected.sources.0.configMap.items.0.path
|
- spec.volumes.0.projected.sources.0.configMap.items.0.path
|
||||||
options:
|
options:
|
||||||
delimiter: '/'
|
delimiter: '/'
|
||||||
@@ -1024,7 +1024,7 @@ spec:
|
|||||||
- select:
|
- select:
|
||||||
kind: Pod
|
kind: Pod
|
||||||
name: pod1
|
name: pod1
|
||||||
fieldPaths:
|
fieldPaths:
|
||||||
- spec.volumes.0.projected.sources.0.configMap.items.0.path
|
- spec.volumes.0.projected.sources.0.configMap.items.0.path
|
||||||
options:
|
options:
|
||||||
delimiter: '/'
|
delimiter: '/'
|
||||||
@@ -1100,7 +1100,7 @@ spec:
|
|||||||
- select:
|
- select:
|
||||||
kind: Pod
|
kind: Pod
|
||||||
name: pod1
|
name: pod1
|
||||||
fieldPaths:
|
fieldPaths:
|
||||||
- spec.volumes.0.projected.sources.0.configMap.items.0.path
|
- spec.volumes.0.projected.sources.0.configMap.items.0.path
|
||||||
options:
|
options:
|
||||||
delimiter: '/'
|
delimiter: '/'
|
||||||
@@ -1176,7 +1176,7 @@ spec:
|
|||||||
- select:
|
- select:
|
||||||
kind: Pod
|
kind: Pod
|
||||||
name: pod1
|
name: pod1
|
||||||
fieldPaths:
|
fieldPaths:
|
||||||
- spec.volumes.0.projected.sources.0.configMap.items.0.path
|
- spec.volumes.0.projected.sources.0.configMap.items.0.path
|
||||||
options:
|
options:
|
||||||
delimiter: '/'
|
delimiter: '/'
|
||||||
@@ -1212,7 +1212,7 @@ metadata:
|
|||||||
targets:
|
targets:
|
||||||
- select:
|
- select:
|
||||||
name: deploy1
|
name: deploy1
|
||||||
fieldPaths:
|
fieldPaths:
|
||||||
- spec.template.spec.containers
|
- spec.template.spec.containers
|
||||||
options:
|
options:
|
||||||
create: true
|
create: true
|
||||||
@@ -1223,7 +1223,7 @@ metadata:
|
|||||||
targets:
|
targets:
|
||||||
- select:
|
- select:
|
||||||
name: deploy2
|
name: deploy2
|
||||||
fieldPaths:
|
fieldPaths:
|
||||||
- spec.template.spec.containers
|
- spec.template.spec.containers
|
||||||
`,
|
`,
|
||||||
expected: `apiVersion: v1
|
expected: `apiVersion: v1
|
||||||
@@ -1285,12 +1285,12 @@ spec:
|
|||||||
kind: Pod
|
kind: Pod
|
||||||
name: pod
|
name: pod
|
||||||
fieldPath: spec.containers
|
fieldPath: spec.containers
|
||||||
options:
|
options:
|
||||||
delimiter: "/"
|
delimiter: "/"
|
||||||
targets:
|
targets:
|
||||||
- select:
|
- select:
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
fieldPaths:
|
fieldPaths:
|
||||||
- spec.template.spec.containers
|
- spec.template.spec.containers
|
||||||
`,
|
`,
|
||||||
expectedErr: "delimiter option can only be used with scalar nodes",
|
expectedErr: "delimiter option can only be used with scalar nodes",
|
||||||
@@ -1331,9 +1331,9 @@ spec:
|
|||||||
targets:
|
targets:
|
||||||
- select:
|
- select:
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
fieldPaths:
|
fieldPaths:
|
||||||
- spec.template.spec.containers
|
- spec.template.spec.containers
|
||||||
options:
|
options:
|
||||||
delimiter: "/"
|
delimiter: "/"
|
||||||
`,
|
`,
|
||||||
expectedErr: "delimiter option can only be used with scalar nodes",
|
expectedErr: "delimiter option can only be used with scalar nodes",
|
||||||
@@ -1354,7 +1354,7 @@ metadata:
|
|||||||
targets:
|
targets:
|
||||||
- select:
|
- select:
|
||||||
name: custom
|
name: custom
|
||||||
fieldPaths:
|
fieldPaths:
|
||||||
- metadata.annotations.[f.g.h/i-j]
|
- metadata.annotations.[f.g.h/i-j]
|
||||||
`,
|
`,
|
||||||
expected: `apiVersion: v1
|
expected: `apiVersion: v1
|
||||||
@@ -1432,6 +1432,247 @@ spec:
|
|||||||
version: latest
|
version: latest
|
||||||
property: second`,
|
property: second`,
|
||||||
},
|
},
|
||||||
|
"one replacements target has multiple value": {
|
||||||
|
input: `apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: sample-deploy
|
||||||
|
name: sample-deploy
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: sample-deploy
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: sample-deploy
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- image: nginx
|
||||||
|
name: main
|
||||||
|
env:
|
||||||
|
- name: deployment-name
|
||||||
|
value: XXXXX
|
||||||
|
- name: foo
|
||||||
|
value: bar
|
||||||
|
- image: nginx
|
||||||
|
name: sidecar
|
||||||
|
env:
|
||||||
|
- name: deployment-name
|
||||||
|
value: YYYYY
|
||||||
|
`,
|
||||||
|
replacements: `replacements:
|
||||||
|
- source:
|
||||||
|
kind: Deployment
|
||||||
|
name: sample-deploy
|
||||||
|
fieldPath: metadata.name
|
||||||
|
targets:
|
||||||
|
- select:
|
||||||
|
kind: Deployment
|
||||||
|
fieldPaths:
|
||||||
|
- spec.template.spec.containers.[image=nginx].env.[name=deployment-name].value
|
||||||
|
`,
|
||||||
|
expected: `apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: sample-deploy
|
||||||
|
name: sample-deploy
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: sample-deploy
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: sample-deploy
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- image: nginx
|
||||||
|
name: main
|
||||||
|
env:
|
||||||
|
- name: deployment-name
|
||||||
|
value: sample-deploy
|
||||||
|
- name: foo
|
||||||
|
value: bar
|
||||||
|
- image: nginx
|
||||||
|
name: sidecar
|
||||||
|
env:
|
||||||
|
- name: deployment-name
|
||||||
|
value: sample-deploy`,
|
||||||
|
},
|
||||||
|
"index contains '*' character": {
|
||||||
|
input: `apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: sample-deploy
|
||||||
|
name: sample-deploy
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: sample-deploy
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: sample-deploy
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- image: nginx
|
||||||
|
name: main
|
||||||
|
env:
|
||||||
|
- name: deployment-name
|
||||||
|
value: XXXXX
|
||||||
|
`,
|
||||||
|
replacements: `replacements:
|
||||||
|
- source:
|
||||||
|
kind: Deployment
|
||||||
|
name: sample-deploy
|
||||||
|
fieldPath: metadata.name
|
||||||
|
targets:
|
||||||
|
- select:
|
||||||
|
kind: Deployment
|
||||||
|
fieldPaths:
|
||||||
|
- spec.template.spec.containers.*.env.[name=deployment-name].value
|
||||||
|
`,
|
||||||
|
expected: `apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: sample-deploy
|
||||||
|
name: sample-deploy
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: sample-deploy
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: sample-deploy
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- image: nginx
|
||||||
|
name: main
|
||||||
|
env:
|
||||||
|
- name: deployment-name
|
||||||
|
value: sample-deploy`,
|
||||||
|
},
|
||||||
|
"list index contains '*' character": {
|
||||||
|
input: `apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: sample-deploy
|
||||||
|
name: sample-deploy
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: sample-deploy
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: sample-deploy
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- image: nginx
|
||||||
|
name: main
|
||||||
|
env:
|
||||||
|
- name: deployment-name
|
||||||
|
value: XXXXX
|
||||||
|
- name: foo
|
||||||
|
value: bar
|
||||||
|
- image: nginx
|
||||||
|
name: sidecar
|
||||||
|
env:
|
||||||
|
- name: deployment-name
|
||||||
|
value: YYYYY
|
||||||
|
`,
|
||||||
|
replacements: `replacements:
|
||||||
|
- source:
|
||||||
|
kind: Deployment
|
||||||
|
name: sample-deploy
|
||||||
|
fieldPath: metadata.name
|
||||||
|
targets:
|
||||||
|
- select:
|
||||||
|
kind: Deployment
|
||||||
|
fieldPaths:
|
||||||
|
- spec.template.spec.containers.*.env.[name=deployment-name].value
|
||||||
|
`,
|
||||||
|
expected: `apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: sample-deploy
|
||||||
|
name: sample-deploy
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: sample-deploy
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: sample-deploy
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- image: nginx
|
||||||
|
name: main
|
||||||
|
env:
|
||||||
|
- name: deployment-name
|
||||||
|
value: sample-deploy
|
||||||
|
- name: foo
|
||||||
|
value: bar
|
||||||
|
- image: nginx
|
||||||
|
name: sidecar
|
||||||
|
env:
|
||||||
|
- name: deployment-name
|
||||||
|
value: sample-deploy`,
|
||||||
|
},
|
||||||
|
"index contains '*' character and create options": {
|
||||||
|
input: `apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: sample-deploy
|
||||||
|
name: sample-deploy
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: sample-deploy
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: sample-deploy
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- image: nginx
|
||||||
|
name: main
|
||||||
|
env:
|
||||||
|
- name: other-env
|
||||||
|
value: YYYYY
|
||||||
|
`,
|
||||||
|
replacements: `replacements:
|
||||||
|
- source:
|
||||||
|
kind: Deployment
|
||||||
|
name: sample-deploy
|
||||||
|
fieldPath: metadata.name
|
||||||
|
targets:
|
||||||
|
- select:
|
||||||
|
kind: Deployment
|
||||||
|
fieldPaths:
|
||||||
|
- spec.template.spec.containers.*.env.[name=deployment-name].value
|
||||||
|
options:
|
||||||
|
create: true
|
||||||
|
`,
|
||||||
|
expectedErr: "cannot support create option in a multi-value target",
|
||||||
|
},
|
||||||
"multiple field paths in target": {
|
"multiple field paths in target": {
|
||||||
input: `apiVersion: v1
|
input: `apiVersion: v1
|
||||||
kind: ConfigMap
|
kind: ConfigMap
|
||||||
@@ -1513,7 +1754,7 @@ spec:
|
|||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
name: pre-deploy
|
name: pre-deploy
|
||||||
annotations:
|
annotations:
|
||||||
internal.config.kubernetes.io/previousNames: deploy,deploy
|
internal.config.kubernetes.io/previousNames: deploy,deploy
|
||||||
internal.config.kubernetes.io/previousKinds: CronJob,Deployment
|
internal.config.kubernetes.io/previousKinds: CronJob,Deployment
|
||||||
internal.config.kubernetes.io/previousNamespaces: default,default
|
internal.config.kubernetes.io/previousNamespaces: default,default
|
||||||
@@ -1535,7 +1776,7 @@ spec:
|
|||||||
- select:
|
- select:
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
name: deploy
|
name: deploy
|
||||||
fieldPaths:
|
fieldPaths:
|
||||||
- spec.template.spec.containers.1.image
|
- spec.template.spec.containers.1.image
|
||||||
`,
|
`,
|
||||||
expected: `apiVersion: v1
|
expected: `apiVersion: v1
|
||||||
@@ -1556,7 +1797,6 @@ spec:
|
|||||||
name: postgresdb
|
name: postgresdb
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
|
|
||||||
"replacement source.fieldPath does not exist": {
|
"replacement source.fieldPath does not exist": {
|
||||||
input: `apiVersion: v1
|
input: `apiVersion: v1
|
||||||
kind: ConfigMap
|
kind: ConfigMap
|
||||||
@@ -1628,7 +1868,7 @@ spec:
|
|||||||
targets:
|
targets:
|
||||||
- select:
|
- select:
|
||||||
annotationSelector: foo=bar-1
|
annotationSelector: foo=bar-1
|
||||||
fieldPaths:
|
fieldPaths:
|
||||||
- spec.template.spec.containers.1.image
|
- spec.template.spec.containers.1.image
|
||||||
`,
|
`,
|
||||||
expected: `apiVersion: v1
|
expected: `apiVersion: v1
|
||||||
@@ -1702,7 +1942,7 @@ spec:
|
|||||||
targets:
|
targets:
|
||||||
- select:
|
- select:
|
||||||
labelSelector: foo=bar-1
|
labelSelector: foo=bar-1
|
||||||
fieldPaths:
|
fieldPaths:
|
||||||
- spec.template.spec.containers.1.image
|
- spec.template.spec.containers.1.image
|
||||||
`,
|
`,
|
||||||
expected: `apiVersion: v1
|
expected: `apiVersion: v1
|
||||||
@@ -1778,7 +2018,7 @@ spec:
|
|||||||
kind: Deployment
|
kind: Deployment
|
||||||
reject:
|
reject:
|
||||||
- labelSelector: foo=bar-2
|
- labelSelector: foo=bar-2
|
||||||
fieldPaths:
|
fieldPaths:
|
||||||
- spec.template.spec.containers.1.image
|
- spec.template.spec.containers.1.image
|
||||||
`,
|
`,
|
||||||
expected: `apiVersion: v1
|
expected: `apiVersion: v1
|
||||||
@@ -1810,6 +2050,310 @@ spec:
|
|||||||
name: nginx-tagged
|
name: nginx-tagged
|
||||||
- image: postgres:1.8.0
|
- image: postgres:1.8.0
|
||||||
name: postgresdb
|
name: postgresdb
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
"string source -> integer target": {
|
||||||
|
input: `apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: config
|
||||||
|
data:
|
||||||
|
PORT: "8080"
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: pod
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- image: busybox
|
||||||
|
name: myapp-container
|
||||||
|
ports:
|
||||||
|
- containerPort: 80
|
||||||
|
`,
|
||||||
|
replacements: `replacements:
|
||||||
|
- source:
|
||||||
|
kind: ConfigMap
|
||||||
|
name: config
|
||||||
|
fieldPath: data.PORT
|
||||||
|
targets:
|
||||||
|
- select:
|
||||||
|
kind: Pod
|
||||||
|
fieldPaths:
|
||||||
|
- spec.containers.0.ports.0.containerPort
|
||||||
|
`,
|
||||||
|
expected: `apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: config
|
||||||
|
data:
|
||||||
|
PORT: "8080"
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: pod
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- image: busybox
|
||||||
|
name: myapp-container
|
||||||
|
ports:
|
||||||
|
- containerPort: 8080
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
"string source -> boolean target": {
|
||||||
|
input: `apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: config
|
||||||
|
data:
|
||||||
|
MOUNT_TOKEN: "true"
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: pod
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- image: busybox
|
||||||
|
name: myapp-container
|
||||||
|
automountServiceAccountToken: false
|
||||||
|
`,
|
||||||
|
replacements: `replacements:
|
||||||
|
- source:
|
||||||
|
kind: ConfigMap
|
||||||
|
name: config
|
||||||
|
fieldPath: data.MOUNT_TOKEN
|
||||||
|
targets:
|
||||||
|
- select:
|
||||||
|
kind: Pod
|
||||||
|
fieldPaths:
|
||||||
|
- spec.containers.0.automountServiceAccountToken
|
||||||
|
`,
|
||||||
|
expected: `apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: config
|
||||||
|
data:
|
||||||
|
MOUNT_TOKEN: "true"
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: pod
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- image: busybox
|
||||||
|
name: myapp-container
|
||||||
|
automountServiceAccountToken: true
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
// TODO: This is inconsistent with expectations; creating a numerical string would be
|
||||||
|
// expected, unless we had knowledge of the intended type of the field to be
|
||||||
|
// created.
|
||||||
|
"numerical string source -> integer creation": {
|
||||||
|
input: `apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: config
|
||||||
|
data:
|
||||||
|
PORT: "8080"
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: pod
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- image: busybox
|
||||||
|
name: myapp-container
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
`,
|
||||||
|
replacements: `replacements:
|
||||||
|
- source:
|
||||||
|
kind: ConfigMap
|
||||||
|
name: config
|
||||||
|
fieldPath: data.PORT
|
||||||
|
targets:
|
||||||
|
- select:
|
||||||
|
kind: Pod
|
||||||
|
fieldPaths:
|
||||||
|
- spec.containers.0.ports.0.containerPort
|
||||||
|
- spec.containers.0.ports.0.name
|
||||||
|
options:
|
||||||
|
create: true
|
||||||
|
`,
|
||||||
|
expected: `apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: config
|
||||||
|
data:
|
||||||
|
PORT: "8080"
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: pod
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- image: busybox
|
||||||
|
name: myapp-container
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
containerPort: 8080
|
||||||
|
name: 8080
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
"integer source -> string target": {
|
||||||
|
input: `apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: config
|
||||||
|
data:
|
||||||
|
PORT: "8080"
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: pod
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- image: busybox
|
||||||
|
name: myapp-container
|
||||||
|
ports:
|
||||||
|
- containerPort: 80
|
||||||
|
`,
|
||||||
|
replacements: `replacements:
|
||||||
|
- source:
|
||||||
|
kind: Pod
|
||||||
|
name: pod
|
||||||
|
fieldPath: spec.containers.0.ports.0.containerPort
|
||||||
|
targets:
|
||||||
|
- select:
|
||||||
|
kind: ConfigMap
|
||||||
|
fieldPaths:
|
||||||
|
- data.PORT
|
||||||
|
`,
|
||||||
|
expected: `apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: config
|
||||||
|
data:
|
||||||
|
PORT: "80"
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: pod
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- image: busybox
|
||||||
|
name: myapp-container
|
||||||
|
ports:
|
||||||
|
- containerPort: 80
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
"boolean source -> string target": {
|
||||||
|
input: `apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: config
|
||||||
|
data:
|
||||||
|
MOUNT_TOKEN: "true"
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: pod
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- image: busybox
|
||||||
|
name: myapp-container
|
||||||
|
automountServiceAccountToken: false
|
||||||
|
`,
|
||||||
|
replacements: `replacements:
|
||||||
|
- source:
|
||||||
|
kind: Pod
|
||||||
|
name: pod
|
||||||
|
fieldPath: spec.containers.0.automountServiceAccountToken
|
||||||
|
targets:
|
||||||
|
- select:
|
||||||
|
kind: ConfigMap
|
||||||
|
fieldPaths:
|
||||||
|
- data.MOUNT_TOKEN
|
||||||
|
`,
|
||||||
|
expected: `apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: config
|
||||||
|
data:
|
||||||
|
MOUNT_TOKEN: "false"
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: pod
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- image: busybox
|
||||||
|
name: myapp-container
|
||||||
|
automountServiceAccountToken: false
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
// TODO: This result is expected, but we should create a string and not an
|
||||||
|
// integer if we could know that the target type should be one. As a result,
|
||||||
|
// the actual ConfigMap produces here cannot be applied.
|
||||||
|
"integer source -> integer creation": {
|
||||||
|
input: `apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: config
|
||||||
|
data:
|
||||||
|
FOO: "Bar"
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: pod
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- image: busybox
|
||||||
|
name: myapp-container
|
||||||
|
ports:
|
||||||
|
- containerPort: 80
|
||||||
|
`,
|
||||||
|
replacements: `replacements:
|
||||||
|
- source:
|
||||||
|
kind: Pod
|
||||||
|
name: pod
|
||||||
|
fieldPath: spec.containers.0.ports.0.containerPort
|
||||||
|
targets:
|
||||||
|
- select:
|
||||||
|
kind: ConfigMap
|
||||||
|
fieldPaths:
|
||||||
|
- data.PORT
|
||||||
|
options:
|
||||||
|
create: true
|
||||||
|
`,
|
||||||
|
expected: `apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: config
|
||||||
|
data:
|
||||||
|
FOO: "Bar"
|
||||||
|
PORT: 80
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Pod
|
||||||
|
metadata:
|
||||||
|
name: pod
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- image: busybox
|
||||||
|
name: myapp-container
|
||||||
|
ports:
|
||||||
|
- containerPort: 80
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// Copyright 2022 The Kubernetes Authors.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
package replicacount
|
package replicacount
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// Copyright 2022 The Kubernetes Authors.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
package replicacount
|
package replicacount
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -41,5 +44,5 @@ func (rc Filter) run(node *yaml.RNode) (*yaml.RNode, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (rc Filter) set(node *yaml.RNode) error {
|
func (rc Filter) set(node *yaml.RNode) error {
|
||||||
return rc.trackableSetter.SetScalar(strconv.FormatInt(rc.Replica.Count, 10))(node)
|
return rc.trackableSetter.SetEntry("", strconv.FormatInt(rc.Replica.Count, 10), yaml.NodeTagInt)(node)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// Copyright 2022 The Kubernetes Authors.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
package replicacount
|
package replicacount
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -192,6 +195,7 @@ spec:
|
|||||||
expectedSetValueArgs: []filtertest_test.SetValueArg{
|
expectedSetValueArgs: []filtertest_test.SetValueArg{
|
||||||
{
|
{
|
||||||
Value: "42",
|
Value: "42",
|
||||||
|
Tag: "!!int",
|
||||||
NodePath: []string{"spec", "replicas"},
|
NodePath: []string{"spec", "replicas"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ require (
|
|||||||
github.com/pkg/errors v0.9.1
|
github.com/pkg/errors v0.9.1
|
||||||
github.com/stretchr/testify v1.7.0
|
github.com/stretchr/testify v1.7.0
|
||||||
gopkg.in/yaml.v2 v2.4.0
|
gopkg.in/yaml.v2 v2.4.0
|
||||||
k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e
|
k8s.io/kube-openapi v0.0.0-20220401212409-b28bf2818661
|
||||||
sigs.k8s.io/kustomize/kyaml v0.13.3
|
sigs.k8s.io/kustomize/kyaml v0.13.7
|
||||||
sigs.k8s.io/yaml v1.2.0
|
sigs.k8s.io/yaml v1.2.0
|
||||||
)
|
)
|
||||||
|
|||||||
39
api/go.sum
39
api/go.sum
@@ -78,6 +78,7 @@ github.com/evanphx/json-patch v4.11.0+incompatible h1:glyUF9yIYtMHzn8xaKw5rMhdWc
|
|||||||
github.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
github.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||||
|
github.com/getkin/kin-openapi v0.76.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSyhcnluiMv+Xg=
|
||||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||||
github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w=
|
github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w=
|
||||||
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
|
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
|
||||||
@@ -85,8 +86,10 @@ github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9
|
|||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||||
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
|
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
|
||||||
github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w=
|
github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
|
||||||
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||||
|
github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY=
|
||||||
|
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||||
github.com/go-openapi/jsonreference v0.19.3 h1:5cxNfTy0UVC3X8JL5ymxzyoUZmo8iZb+jeTWn7tUa8o=
|
github.com/go-openapi/jsonreference v0.19.3 h1:5cxNfTy0UVC3X8JL5ymxzyoUZmo8iZb+jeTWn7tUa8o=
|
||||||
github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
|
github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
|
||||||
github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY=
|
github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY=
|
||||||
@@ -125,6 +128,8 @@ github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw
|
|||||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||||
|
github.com/google/gnostic v0.5.7-v3refs h1:FhTMOKj2VhjpouxvWJAV1TL304uMlb9zcDqkl6cEI54=
|
||||||
|
github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ=
|
||||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||||
@@ -138,6 +143,8 @@ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
|||||||
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
||||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
|
github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g=
|
||||||
|
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||||
github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||||
@@ -155,13 +162,11 @@ github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLe
|
|||||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
|
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
|
||||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
|
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
|
||||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
|
||||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||||
github.com/googleapis/gnostic v0.5.1 h1:A8Yhf6EtqTv9RMsU6MQTyrtV1TjWlR6xU9BsZIwuTCM=
|
|
||||||
github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU=
|
|
||||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||||
|
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
||||||
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
|
||||||
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
|
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
|
||||||
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
|
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
|
||||||
@@ -247,11 +252,11 @@ github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNX
|
|||||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||||
|
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
|
||||||
github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
|
github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
|
||||||
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||||
github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk=
|
github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk=
|
||||||
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
|
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
|
||||||
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
|
||||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns=
|
github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns=
|
||||||
github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
|
github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
|
||||||
@@ -440,8 +445,9 @@ golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3
|
|||||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ=
|
|
||||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
|
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
|
||||||
|
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
@@ -481,6 +487,7 @@ golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjs
|
|||||||
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||||
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
|
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
|
||||||
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||||
|
golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||||
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||||
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||||
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||||
@@ -496,9 +503,11 @@ golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4f
|
|||||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||||
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||||
|
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||||
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
|
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
|
||||||
@@ -560,6 +569,7 @@ google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6D
|
|||||||
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
|
google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||||
@@ -601,8 +611,10 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD
|
|||||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||||
google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
|
|
||||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||||
|
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||||
|
google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
|
||||||
|
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||||
@@ -614,6 +626,7 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
|||||||
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
@@ -627,15 +640,17 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
|
|||||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||||
k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
|
k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
|
||||||
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
|
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
|
||||||
k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e h1:KLHHjkdQFomZy8+06csTWZ0m1343QqxZhR2LJ1OxCYM=
|
k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
|
||||||
k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw=
|
k8s.io/kube-openapi v0.0.0-20220401212409-b28bf2818661 h1:nqYOUleKLC/0P1zbU29F5q6aoezM6MOAVz+iyfQbZ5M=
|
||||||
|
k8s.io/kube-openapi v0.0.0-20220401212409-b28bf2818661/go.mod h1:daOouuuwd9JXpv1L7Y34iV3yf6nxzipkKMWWlqlvK9M=
|
||||||
|
k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||||
sigs.k8s.io/kustomize/kyaml v0.13.3 h1:tNNQIC+8cc+aXFTVg+RtQAOsjwUdYBZRAgYOVI3RBc4=
|
sigs.k8s.io/kustomize/kyaml v0.13.7 h1:/EZ/nPaLUzeJKF/BuJ4QCuMVJWiEVoI8iftOHY3g3tk=
|
||||||
sigs.k8s.io/kustomize/kyaml v0.13.3/go.mod h1:/ya3Gk4diiQzlE4mBh7wykyLRFZNvqlbh+JnwQ9Vhrc=
|
sigs.k8s.io/kustomize/kyaml v0.13.7/go.mod h1:6K+IUOuir3Y7nucPRAjw9yth04KSWBnP5pqUTGwj/qU=
|
||||||
sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
|
sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
|
||||||
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
|
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
|
||||||
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
|
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
|
||||||
|
|||||||
@@ -341,6 +341,7 @@ data:
|
|||||||
// The return value indicates whether we should skip the rest of the test case
|
// The return value indicates whether we should skip the rest of the test case
|
||||||
// due to the error result.
|
// due to the error result.
|
||||||
func SkipRest(t *testing.T, desc string, err error, contains string) bool {
|
func SkipRest(t *testing.T, desc string, err error, contains string) bool {
|
||||||
|
t.Helper()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if len(contains) == 0 {
|
if len(contains) == 0 {
|
||||||
t.Errorf("case %q, expect nil error but got %q", desc, err.Error())
|
t.Errorf("case %q, expect nil error but got %q", desc, err.Error())
|
||||||
|
|||||||
@@ -14,37 +14,53 @@ func IsImageMatched(s, t string) bool {
|
|||||||
// Tag values are limited to [a-zA-Z0-9_.{}-].
|
// Tag values are limited to [a-zA-Z0-9_.{}-].
|
||||||
// Some tools like Bazel rules_k8s allow tag patterns with {} characters.
|
// Some tools like Bazel rules_k8s allow tag patterns with {} characters.
|
||||||
// More info: https://github.com/bazelbuild/rules_k8s/pull/423
|
// More info: https://github.com/bazelbuild/rules_k8s/pull/423
|
||||||
pattern, _ := regexp.Compile("^" + t + "(@sha256)?(:[a-zA-Z0-9_.{}-]*)?$")
|
pattern, _ := regexp.Compile("^" + t + "(:[a-zA-Z0-9_.{}-]*)?(@sha256:[a-zA-Z0-9_.{}-]*)?$")
|
||||||
return pattern.MatchString(s)
|
return pattern.MatchString(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Split separates and returns the name and tag parts
|
// Split separates and returns the name and tag parts
|
||||||
// from the image string using either colon `:` or at `@` separators.
|
// from the image string using either colon `:` or at `@` separators.
|
||||||
// Note that the returned tag keeps its separator.
|
// image reference pattern: [[host[:port]/]component/]component[:tag][@digest]
|
||||||
func Split(imageName string) (name string, tag string) {
|
func Split(imageName string) (name string, tag string, digest string) {
|
||||||
// check if image name contains a domain
|
// check if image name contains a domain
|
||||||
// if domain is present, ignore domain and check for `:`
|
// if domain is present, ignore domain and check for `:`
|
||||||
ic := -1
|
searchName := imageName
|
||||||
if slashIndex := strings.Index(imageName, "/"); slashIndex < 0 {
|
slashIndex := strings.Index(imageName, "/")
|
||||||
ic = strings.LastIndex(imageName, ":")
|
if slashIndex > 0 {
|
||||||
|
searchName = imageName[slashIndex:]
|
||||||
} else {
|
} else {
|
||||||
lastIc := strings.LastIndex(imageName[slashIndex:], ":")
|
slashIndex = 0
|
||||||
// set ic only if `:` is present
|
|
||||||
if lastIc > 0 {
|
|
||||||
ic = slashIndex + lastIc
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ia := strings.LastIndex(imageName, "@")
|
|
||||||
if ic < 0 && ia < 0 {
|
|
||||||
return imageName, ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
i := ic
|
id := strings.Index(searchName, "@")
|
||||||
if ia > 0 {
|
ic := strings.Index(searchName, ":")
|
||||||
i = ia
|
|
||||||
|
// no tag or digest
|
||||||
|
if ic < 0 && id < 0 {
|
||||||
|
return imageName, "", ""
|
||||||
}
|
}
|
||||||
|
|
||||||
name = imageName[:i]
|
// digest only
|
||||||
tag = imageName[i:]
|
if id >= 0 && (id < ic || ic < 0) {
|
||||||
return
|
id += slashIndex
|
||||||
|
name = imageName[:id]
|
||||||
|
digest = strings.TrimPrefix(imageName[id:], "@")
|
||||||
|
return name, "", digest
|
||||||
|
}
|
||||||
|
|
||||||
|
// tag and digest
|
||||||
|
if id >= 0 && ic >= 0 {
|
||||||
|
id += slashIndex
|
||||||
|
ic += slashIndex
|
||||||
|
name = imageName[:ic]
|
||||||
|
tag = strings.TrimPrefix(imageName[ic:id], ":")
|
||||||
|
digest = strings.TrimPrefix(imageName[id:], "@")
|
||||||
|
return name, tag, digest
|
||||||
|
}
|
||||||
|
|
||||||
|
// tag only
|
||||||
|
ic += slashIndex
|
||||||
|
name = imageName[:ic]
|
||||||
|
tag = strings.TrimPrefix(imageName[ic:], ":")
|
||||||
|
return name, tag, ""
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,11 +23,23 @@ func TestIsImageMatched(t *testing.T) {
|
|||||||
isMatched: true,
|
isMatched: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
testName: "name is match",
|
testName: "name is match with tag",
|
||||||
value: "nginx:12345",
|
value: "nginx:12345",
|
||||||
name: "nginx",
|
name: "nginx",
|
||||||
isMatched: true,
|
isMatched: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
testName: "name is match with digest",
|
||||||
|
value: "nginx@sha256:xyz",
|
||||||
|
name: "nginx",
|
||||||
|
isMatched: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
testName: "name is match with tag and digest",
|
||||||
|
value: "nginx:12345@sha256:xyz",
|
||||||
|
name: "nginx",
|
||||||
|
isMatched: true,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
testName: "name is not a match",
|
testName: "name is not a match",
|
||||||
value: "apache:12345",
|
value: "apache:12345",
|
||||||
@@ -49,32 +61,65 @@ func TestSplit(t *testing.T) {
|
|||||||
value string
|
value string
|
||||||
name string
|
name string
|
||||||
tag string
|
tag string
|
||||||
|
digest string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
testName: "no tag",
|
testName: "no tag",
|
||||||
value: "nginx",
|
value: "nginx",
|
||||||
name: "nginx",
|
name: "nginx",
|
||||||
tag: "",
|
tag: "",
|
||||||
|
digest: "",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
testName: "with tag",
|
testName: "with tag",
|
||||||
value: "nginx:1.2.3",
|
value: "nginx:1.2.3",
|
||||||
name: "nginx",
|
name: "nginx",
|
||||||
tag: ":1.2.3",
|
tag: "1.2.3",
|
||||||
|
digest: "",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
testName: "with digest",
|
testName: "with digest",
|
||||||
value: "nginx@12345",
|
value: "nginx@sha256:12345",
|
||||||
name: "nginx",
|
name: "nginx",
|
||||||
tag: "@12345",
|
tag: "",
|
||||||
|
digest: "sha256:12345",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
testName: "with tag and digest",
|
||||||
|
value: "nginx:1.2.3@sha256:12345",
|
||||||
|
name: "nginx",
|
||||||
|
tag: "1.2.3",
|
||||||
|
digest: "sha256:12345",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
testName: "with domain",
|
||||||
|
value: "docker.io/nginx:1.2.3",
|
||||||
|
name: "docker.io/nginx",
|
||||||
|
tag: "1.2.3",
|
||||||
|
digest: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
testName: "with domain and port",
|
||||||
|
value: "foo.com:443/nginx:1.2.3",
|
||||||
|
name: "foo.com:443/nginx",
|
||||||
|
tag: "1.2.3",
|
||||||
|
digest: "",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
testName: "with domain, port, tag and digest",
|
||||||
|
value: "foo.com:443/nginx:1.2.3@sha256:12345",
|
||||||
|
name: "foo.com:443/nginx",
|
||||||
|
tag: "1.2.3",
|
||||||
|
digest: "sha256:12345",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
t.Run(tc.testName, func(t *testing.T) {
|
t.Run(tc.testName, func(t *testing.T) {
|
||||||
name, tag := Split(tc.value)
|
name, tag, digest := Split(tc.value)
|
||||||
assert.Equal(t, tc.name, name)
|
assert.Equal(t, tc.name, name)
|
||||||
assert.Equal(t, tc.tag, tag)
|
assert.Equal(t, tc.tag, tag)
|
||||||
|
assert.Equal(t, tc.digest, digest)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -113,7 +113,6 @@ func debug(fMap filterMap) {
|
|||||||
// 'spec/scaleTargetRef/name' field. Return a filter that can do that.
|
// 'spec/scaleTargetRef/name' field. Return a filter that can do that.
|
||||||
func (t *nameReferenceTransformer) determineFilters(
|
func (t *nameReferenceTransformer) determineFilters(
|
||||||
resources []*resource.Resource) (fMap filterMap) {
|
resources []*resource.Resource) (fMap filterMap) {
|
||||||
|
|
||||||
// We cache the resource OrgId values because they don't change and otherwise are very visible in a memory pprof
|
// We cache the resource OrgId values because they don't change and otherwise are very visible in a memory pprof
|
||||||
resourceOrgIds := make([]resid.ResId, len(resources))
|
resourceOrgIds := make([]resid.ResId, len(resources))
|
||||||
for i, resource := range resources {
|
for i, resource := range resources {
|
||||||
|
|||||||
@@ -107,7 +107,6 @@ func (ra *ResAccumulator) findVarValueFromResources(v types.Var) (interface{}, e
|
|||||||
for _, res := range ra.resMap.Resources() {
|
for _, res := range ra.resMap.Resources() {
|
||||||
for _, varName := range res.GetRefVarNames() {
|
for _, varName := range res.GetRefVarNames() {
|
||||||
if varName == v.Name {
|
if varName == v.Name {
|
||||||
//nolint: staticcheck
|
|
||||||
s, err := res.GetFieldValue(v.FieldRef.FieldPath)
|
s, err := res.GetFieldValue(v.FieldRef.FieldPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf(
|
return "", fmt.Errorf(
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func makeResAccumulator(t *testing.T) *ResAccumulator {
|
func makeResAccumulator(t *testing.T) *ResAccumulator {
|
||||||
|
t.Helper()
|
||||||
ra := MakeEmptyAccumulator()
|
ra := MakeEmptyAccumulator()
|
||||||
err := ra.MergeConfig(builtinconfig.MakeDefaultConfig())
|
err := ra.MergeConfig(builtinconfig.MakeDefaultConfig())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -133,6 +134,7 @@ func TestResolveVarsOneUnused(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func expectLog(t *testing.T, log bytes.Buffer, expect string) {
|
func expectLog(t *testing.T, log bytes.Buffer, expect string) {
|
||||||
|
t.Helper()
|
||||||
if !strings.Contains(log.String(), expect) {
|
if !strings.Contains(log.String(), expect) {
|
||||||
t.Fatalf("expected log containing '%s', got '%s'", expect, log.String())
|
t.Fatalf("expected log containing '%s', got '%s'", expect, log.String())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ package builtins
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
|
||||||
"sigs.k8s.io/kustomize/api/filters/replacement"
|
"sigs.k8s.io/kustomize/api/filters/replacement"
|
||||||
"sigs.k8s.io/kustomize/api/resmap"
|
"sigs.k8s.io/kustomize/api/resmap"
|
||||||
@@ -35,11 +36,29 @@ func (p *ReplacementTransformerPlugin) Config(
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
repl := types.Replacement{}
|
// find if the path contains a a list of replacements or a single replacement
|
||||||
if err := yaml.Unmarshal(content, &repl); err != nil {
|
var replacement interface{}
|
||||||
|
err = yaml.Unmarshal(content, &replacement)
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
p.Replacements = append(p.Replacements, repl)
|
items := reflect.ValueOf(replacement)
|
||||||
|
switch items.Kind() {
|
||||||
|
case reflect.Slice:
|
||||||
|
repl := []types.Replacement{}
|
||||||
|
if err := yaml.Unmarshal(content, &repl); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
p.Replacements = append(p.Replacements, repl...)
|
||||||
|
case reflect.Map:
|
||||||
|
repl := types.Replacement{}
|
||||||
|
if err := yaml.Unmarshal(content, &repl); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
p.Replacements = append(p.Replacements, repl)
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("unsupported replacement type encountered within replacement path: %v", items.Kind())
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// replacement information is already loaded
|
// replacement information is already loaded
|
||||||
p.Replacements = append(p.Replacements, r.Replacement)
|
p.Replacements = append(p.Replacements, r.Replacement)
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ metadata:
|
|||||||
foo: 'bar'
|
foo: 'bar'
|
||||||
data:
|
data:
|
||||||
a: x
|
a: x
|
||||||
b: y
|
b: "y"
|
||||||
c: Hello World
|
c: Hello World
|
||||||
d: "true"
|
d: "true"
|
||||||
`,
|
`,
|
||||||
@@ -181,7 +181,7 @@ metadata:
|
|||||||
river: 'Missouri'
|
river: 'Missouri'
|
||||||
data:
|
data:
|
||||||
a: x
|
a: x
|
||||||
b: y
|
b: "y"
|
||||||
c: Hello World
|
c: Hello World
|
||||||
d: "true"
|
d: "true"
|
||||||
immutable: true
|
immutable: true
|
||||||
|
|||||||
@@ -83,9 +83,15 @@ func setImmutable(
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if opts.Immutable {
|
if opts.Immutable {
|
||||||
if _, err := rn.Pipe(yaml.SetField("immutable", yaml.NewScalarRNode("true"))); err != nil {
|
n := &yaml.Node{
|
||||||
|
Kind: yaml.ScalarNode,
|
||||||
|
Value: "true",
|
||||||
|
Tag: yaml.NodeTagBool,
|
||||||
|
}
|
||||||
|
if _, err := rn.Pipe(yaml.FieldSetter{Name: "immutable", Value: yaml.NewRNode(n)}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,15 +78,15 @@ func (x *RepoSpec) Cleaner(fSys filesys.FileSystem) func() error {
|
|||||||
return func() error { return fSys.RemoveAll(x.Dir.String()) }
|
return func() error { return fSys.RemoveAll(x.Dir.String()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewRepoSpecFromUrl parses git-like urls.
|
// NewRepoSpecFromURL parses git-like urls.
|
||||||
// From strings like git@github.com:someOrg/someRepo.git or
|
// From strings like git@github.com:someOrg/someRepo.git or
|
||||||
// https://github.com/someOrg/someRepo?ref=someHash, extract
|
// https://github.com/someOrg/someRepo?ref=someHash, extract
|
||||||
// the parts.
|
// the parts.
|
||||||
func NewRepoSpecFromUrl(n string) (*RepoSpec, error) {
|
func NewRepoSpecFromURL(n string) (*RepoSpec, error) {
|
||||||
if filepath.IsAbs(n) {
|
if filepath.IsAbs(n) {
|
||||||
return nil, fmt.Errorf("uri looks like abs path: %s", n)
|
return nil, fmt.Errorf("uri looks like abs path: %s", n)
|
||||||
}
|
}
|
||||||
host, orgRepo, path, gitRef, gitSubmodules, suffix, gitTimeout := parseGitUrl(n)
|
host, orgRepo, path, gitRef, gitSubmodules, suffix, gitTimeout := parseGitURL(n)
|
||||||
if orgRepo == "" {
|
if orgRepo == "" {
|
||||||
return nil, fmt.Errorf("url lacks orgRepo: %s", n)
|
return nil, fmt.Errorf("url lacks orgRepo: %s", n)
|
||||||
}
|
}
|
||||||
@@ -108,9 +108,8 @@ const (
|
|||||||
// From strings like git@github.com:someOrg/someRepo.git or
|
// From strings like git@github.com:someOrg/someRepo.git or
|
||||||
// https://github.com/someOrg/someRepo?ref=someHash, extract
|
// https://github.com/someOrg/someRepo?ref=someHash, extract
|
||||||
// the parts.
|
// the parts.
|
||||||
func parseGitUrl(n string) (
|
func parseGitURL(n string) (
|
||||||
host string, orgRepo string, path string, gitRef string, gitSubmodules bool, gitSuff string, gitTimeout time.Duration) {
|
host string, orgRepo string, path string, gitRef string, gitSubmodules bool, gitSuff string, gitTimeout time.Duration) {
|
||||||
|
|
||||||
if strings.Contains(n, gitDelimiter) {
|
if strings.Contains(n, gitDelimiter) {
|
||||||
index := strings.Index(n, gitDelimiter)
|
index := strings.Index(n, gitDelimiter)
|
||||||
// Adding _git/ to host
|
// Adding _git/ to host
|
||||||
@@ -229,7 +228,7 @@ func parseHostSpec(n string) (string, string) {
|
|||||||
if strings.HasSuffix(host, p) {
|
if strings.HasSuffix(host, p) {
|
||||||
i := strings.Index(n, "/")
|
i := strings.Index(n, "/")
|
||||||
if i > -1 {
|
if i > -1 {
|
||||||
host = host + n[0:i+1]
|
host += n[0 : i+1]
|
||||||
n = n[i+1:]
|
n = n[i+1:]
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ var hostNamesRawAndNormalized = [][]string{
|
|||||||
{"git@github.com/", "git@github.com:"},
|
{"git@github.com/", "git@github.com:"},
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeUrl(hostFmt, orgRepo, path, href string) string {
|
func makeURL(hostFmt, orgRepo, path, href string) string {
|
||||||
if len(path) > 0 {
|
if len(path) > 0 {
|
||||||
orgRepo = filepath.Join(orgRepo, path)
|
orgRepo = filepath.Join(orgRepo, path)
|
||||||
}
|
}
|
||||||
@@ -56,8 +56,8 @@ func TestNewRepoSpecFromUrl(t *testing.T) {
|
|||||||
for _, orgRepo := range orgRepos {
|
for _, orgRepo := range orgRepos {
|
||||||
for _, pathName := range pathNames {
|
for _, pathName := range pathNames {
|
||||||
for _, hrefArg := range hrefArgs {
|
for _, hrefArg := range hrefArgs {
|
||||||
uri := makeUrl(hostRaw, orgRepo, pathName, hrefArg)
|
uri := makeURL(hostRaw, orgRepo, pathName, hrefArg)
|
||||||
rs, err := NewRepoSpecFromUrl(uri)
|
rs, err := NewRepoSpecFromURL(uri)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("problem %v", err)
|
t.Errorf("problem %v", err)
|
||||||
}
|
}
|
||||||
@@ -99,7 +99,7 @@ var badData = [][]string{
|
|||||||
|
|
||||||
func TestNewRepoSpecFromUrlErrors(t *testing.T) {
|
func TestNewRepoSpecFromUrlErrors(t *testing.T) {
|
||||||
for _, tuple := range badData {
|
for _, tuple := range badData {
|
||||||
_, err := NewRepoSpecFromUrl(tuple[0])
|
_, err := NewRepoSpecFromURL(tuple[0])
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Error("expected error")
|
t.Error("expected error")
|
||||||
}
|
}
|
||||||
@@ -191,7 +191,7 @@ func TestNewRepoSpecFromUrl_CloneSpecs(t *testing.T) {
|
|||||||
}
|
}
|
||||||
for tn, tc := range testcases {
|
for tn, tc := range testcases {
|
||||||
t.Run(tn, func(t *testing.T) {
|
t.Run(tn, func(t *testing.T) {
|
||||||
rs, err := NewRepoSpecFromUrl(tc.input)
|
rs, err := NewRepoSpecFromURL(tc.input)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, tc.cloneSpec, rs.CloneSpec(), "cloneSpec mismatch")
|
assert.Equal(t, tc.cloneSpec, rs.CloneSpec(), "cloneSpec mismatch")
|
||||||
assert.Equal(t, tc.absPath, rs.AbsPath(), "absPath mismatch")
|
assert.Equal(t, tc.absPath, rs.AbsPath(), "absPath mismatch")
|
||||||
|
|||||||
@@ -19,6 +19,16 @@ func (e YamlFormatError) Error() string {
|
|||||||
return fmt.Sprintf("YAML file [%s] encounters a format error.\n%s\n", e.Path, e.ErrorMsg)
|
return fmt.Sprintf("YAML file [%s] encounters a format error.\n%s\n", e.Path, e.ErrorMsg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MalformedYamlError represents an error that occurred while trying to decode a given YAML.
|
||||||
|
type MalformedYamlError struct {
|
||||||
|
Path string
|
||||||
|
ErrorMsg string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e MalformedYamlError) Error() string {
|
||||||
|
return fmt.Sprintf("%s in File: %s", e.ErrorMsg, e.Path)
|
||||||
|
}
|
||||||
|
|
||||||
// Handler handles YamlFormatError
|
// Handler handles YamlFormatError
|
||||||
func Handler(e error, path string) error {
|
func Handler(e error, path string) error {
|
||||||
if isYAMLSyntaxError(e) {
|
if isYAMLSyntaxError(e) {
|
||||||
@@ -27,9 +37,19 @@ func Handler(e error, path string) error {
|
|||||||
ErrorMsg: e.Error(),
|
ErrorMsg: e.Error(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if IsMalformedYAMLError(e) {
|
||||||
|
return MalformedYamlError{
|
||||||
|
Path: path,
|
||||||
|
ErrorMsg: e.Error(),
|
||||||
|
}
|
||||||
|
}
|
||||||
return e
|
return e
|
||||||
}
|
}
|
||||||
|
|
||||||
func isYAMLSyntaxError(e error) bool {
|
func isYAMLSyntaxError(e error) bool {
|
||||||
return strings.Contains(e.Error(), "error converting YAML to JSON") || strings.Contains(e.Error(), "error unmarshaling JSON")
|
return strings.Contains(e.Error(), "error converting YAML to JSON") || strings.Contains(e.Error(), "error unmarshaling JSON")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func IsMalformedYAMLError(e error) bool {
|
||||||
|
return strings.Contains(e.Error(), "MalformedYAMLError")
|
||||||
|
}
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ const (
|
|||||||
|
|
||||||
var stringToBuiltinPluginTypeMap map[string]BuiltinPluginType
|
var stringToBuiltinPluginTypeMap map[string]BuiltinPluginType
|
||||||
|
|
||||||
func init() {
|
func init() { //nolint:gochecknoinits
|
||||||
stringToBuiltinPluginTypeMap = makeStringToBuiltinPluginTypeMap()
|
stringToBuiltinPluginTypeMap = makeStringToBuiltinPluginTypeMap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -83,7 +83,6 @@ metadata:
|
|||||||
`
|
`
|
||||||
if expected != string(p.Cfg()) {
|
if expected != string(p.Cfg()) {
|
||||||
t.Fatalf("expected cfg '%s', got '%s'", expected, string(p.Cfg()))
|
t.Fatalf("expected cfg '%s', got '%s'", expected, string(p.Cfg()))
|
||||||
|
|
||||||
}
|
}
|
||||||
if len(p.Args()) != 6 {
|
if len(p.Args()) != 6 {
|
||||||
t.Fatalf("unexpected arg len %d, %#v", len(p.Args()), p.Args())
|
t.Fatalf("unexpected arg len %d, %#v", len(p.Args()), p.Args())
|
||||||
|
|||||||
@@ -228,6 +228,17 @@ func (l *Loader) makeBuiltinPlugin(r resid.Gvk) (resmap.Configurable, error) {
|
|||||||
func (l *Loader) loadPlugin(res *resource.Resource) (resmap.Configurable, error) {
|
func (l *Loader) loadPlugin(res *resource.Resource) (resmap.Configurable, error) {
|
||||||
spec := fnplugin.GetFunctionSpec(res)
|
spec := fnplugin.GetFunctionSpec(res)
|
||||||
if spec != nil {
|
if spec != nil {
|
||||||
|
// validation check that function mounts are under the current kustomization directory
|
||||||
|
for _, mount := range spec.Container.StorageMounts {
|
||||||
|
if filepath.IsAbs(mount.Src) {
|
||||||
|
return nil, errors.New(fmt.Sprintf("plugin %s with mount path '%s' is not permitted; "+
|
||||||
|
"mount paths must be relative to the current kustomization directory", res.OrgId(), mount.Src))
|
||||||
|
}
|
||||||
|
if strings.HasPrefix(filepath.Clean(mount.Src), "../") {
|
||||||
|
return nil, errors.New(fmt.Sprintf("plugin %s with mount path '%s' is not permitted; "+
|
||||||
|
"mount paths must be under the current kustomization directory", res.OrgId(), mount.Src))
|
||||||
|
}
|
||||||
|
}
|
||||||
return fnplugin.NewFnPlugin(&l.pc.FnpLoadingOptions), nil
|
return fnplugin.NewFnPlugin(&l.pc.FnpLoadingOptions), nil
|
||||||
}
|
}
|
||||||
return l.loadExecOrGoPlugin(res.OrgId())
|
return l.loadExecOrGoPlugin(res.OrgId())
|
||||||
|
|||||||
@@ -105,10 +105,10 @@ func TestUpdateResourceOptionsWithInvalidHashAnnotationValues(t *testing.T) {
|
|||||||
"TrUe",
|
"TrUe",
|
||||||
"potato",
|
"potato",
|
||||||
}
|
}
|
||||||
for i, c := range cases {
|
for i := range cases {
|
||||||
name := fmt.Sprintf("test%d", i)
|
name := fmt.Sprintf("test%d", i)
|
||||||
in := resmap.New()
|
in := resmap.New()
|
||||||
err := in.Append(makeConfigMap(rf, name, "", &c))
|
err := in.Append(makeConfigMap(rf, name, "", &cases[i]))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
_, err = UpdateResourceOptions(in)
|
_, err = UpdateResourceOptions(in)
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ package target
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
@@ -14,6 +13,7 @@ import (
|
|||||||
"sigs.k8s.io/kustomize/api/ifc"
|
"sigs.k8s.io/kustomize/api/ifc"
|
||||||
"sigs.k8s.io/kustomize/api/internal/accumulator"
|
"sigs.k8s.io/kustomize/api/internal/accumulator"
|
||||||
"sigs.k8s.io/kustomize/api/internal/builtins"
|
"sigs.k8s.io/kustomize/api/internal/builtins"
|
||||||
|
"sigs.k8s.io/kustomize/api/internal/kusterr"
|
||||||
"sigs.k8s.io/kustomize/api/internal/plugins/builtinconfig"
|
"sigs.k8s.io/kustomize/api/internal/plugins/builtinconfig"
|
||||||
"sigs.k8s.io/kustomize/api/internal/plugins/builtinhelpers"
|
"sigs.k8s.io/kustomize/api/internal/plugins/builtinhelpers"
|
||||||
"sigs.k8s.io/kustomize/api/internal/plugins/loader"
|
"sigs.k8s.io/kustomize/api/internal/plugins/loader"
|
||||||
@@ -303,7 +303,9 @@ func (kt *KustTarget) configureExternalGenerators() (
|
|||||||
rm.Replace(r)
|
rm.Replace(r)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ra.AppendAll(rm)
|
if err = ra.AppendAll(rm); err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "configuring external generator")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ra, err := kt.accumulateResources(ra, generatorPaths)
|
ra, err := kt.accumulateResources(ra, generatorPaths)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -347,7 +349,10 @@ func (kt *KustTarget) configureExternalTransformers(transformers []string) ([]*r
|
|||||||
rm.Replace(r)
|
rm.Replace(r)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ra.AppendAll(rm)
|
|
||||||
|
if err = ra.AppendAll(rm); err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "configuring external transformer")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ra, err := kt.accumulateResources(ra, transformerPaths)
|
ra, err := kt.accumulateResources(ra, transformerPaths)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -407,6 +412,9 @@ func (kt *KustTarget) accumulateResources(
|
|||||||
}
|
}
|
||||||
ldr, err := kt.ldr.New(path)
|
ldr, err := kt.ldr.New(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if kusterr.IsMalformedYAMLError(errF) { // Some error occurred while tyring to decode YAML file
|
||||||
|
return nil, errF
|
||||||
|
}
|
||||||
return nil, errors.Wrapf(
|
return nil, errors.Wrapf(
|
||||||
err, "accumulation err='%s'", errF.Error())
|
err, "accumulation err='%s'", errF.Error())
|
||||||
}
|
}
|
||||||
@@ -421,6 +429,9 @@ func (kt *KustTarget) accumulateResources(
|
|||||||
ra, err = kt.accumulateDirectory(ra, ldr, false)
|
ra, err = kt.accumulateDirectory(ra, ldr, false)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if kusterr.IsMalformedYAMLError(errF) { // Some error occurred while tyring to decode YAML file
|
||||||
|
return nil, errF
|
||||||
|
}
|
||||||
return nil, errors.Wrapf(
|
return nil, errors.Wrapf(
|
||||||
err, "accumulation err='%s'", errF.Error())
|
err, "accumulation err='%s'", errF.Error())
|
||||||
}
|
}
|
||||||
@@ -469,9 +480,8 @@ func (kt *KustTarget) accumulateDirectory(
|
|||||||
subKt.kustomization.BuildMetadata = kt.kustomization.BuildMetadata
|
subKt.kustomization.BuildMetadata = kt.kustomization.BuildMetadata
|
||||||
subKt.origin = kt.origin
|
subKt.origin = kt.origin
|
||||||
var bytes []byte
|
var bytes []byte
|
||||||
path := ldr.Root()
|
|
||||||
if openApiPath, exists := subKt.Kustomization().OpenAPI["path"]; exists {
|
if openApiPath, exists := subKt.Kustomization().OpenAPI["path"]; exists {
|
||||||
bytes, err = ldr.Load(filepath.Join(path, openApiPath))
|
bytes, err = ldr.Load(openApiPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
"sigs.k8s.io/kustomize/api/internal/plugins/builtinconfig"
|
"sigs.k8s.io/kustomize/api/internal/plugins/builtinconfig"
|
||||||
"sigs.k8s.io/kustomize/api/internal/plugins/builtinhelpers"
|
"sigs.k8s.io/kustomize/api/internal/plugins/builtinhelpers"
|
||||||
"sigs.k8s.io/kustomize/api/resmap"
|
"sigs.k8s.io/kustomize/api/resmap"
|
||||||
@@ -285,6 +286,13 @@ var transformerConfigurators = map[builtinhelpers.BuiltinPluginType]func(
|
|||||||
if label.IncludeSelectors {
|
if label.IncludeSelectors {
|
||||||
fss, err = fss.MergeAll(tc.CommonLabels)
|
fss, err = fss.MergeAll(tc.CommonLabels)
|
||||||
} else {
|
} else {
|
||||||
|
// merge spec/template/metadata fieldSpec if includeTemplate flag is true
|
||||||
|
if label.IncludeTemplates {
|
||||||
|
fss, err = fss.MergeOne(types.FieldSpec{Path: "spec/template/metadata/labels", CreateIfNotPresent: false})
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "failed to merge template fieldSpec")
|
||||||
|
}
|
||||||
|
}
|
||||||
// only add to metadata by default
|
// only add to metadata by default
|
||||||
fss, err = fss.MergeOne(types.FieldSpec{Path: "metadata/labels", CreateIfNotPresent: true})
|
fss, err = fss.MergeOne(types.FieldSpec{Path: "metadata/labels", CreateIfNotPresent: true})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -257,3 +257,71 @@ metadata:
|
|||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, string(expYaml), string(actYaml))
|
assert.Equal(t, string(expYaml), string(actYaml))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDuplicateExternalGeneratorsForbidden(t *testing.T) {
|
||||||
|
th := kusttest_test.MakeHarness(t)
|
||||||
|
th.WriteK("/generator", `
|
||||||
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
|
kind: Kustomization
|
||||||
|
generators:
|
||||||
|
- |-
|
||||||
|
apiVersion: generators.example/v1
|
||||||
|
kind: ManifestGenerator
|
||||||
|
metadata:
|
||||||
|
name: ManifestGenerator
|
||||||
|
annotations:
|
||||||
|
config.kubernetes.io/function: |
|
||||||
|
container:
|
||||||
|
image: ManifestGenerator:latest
|
||||||
|
spec:
|
||||||
|
image: 'someimage:12345'
|
||||||
|
configPath: config.json
|
||||||
|
- |-
|
||||||
|
apiVersion: generators.example/v1
|
||||||
|
kind: ManifestGenerator
|
||||||
|
metadata:
|
||||||
|
name: ManifestGenerator
|
||||||
|
annotations:
|
||||||
|
config.kubernetes.io/function: |
|
||||||
|
container:
|
||||||
|
image: ManifestGenerator:latest
|
||||||
|
spec:
|
||||||
|
image: 'someimage:12345'
|
||||||
|
configPath: another_config.json
|
||||||
|
`)
|
||||||
|
_, err := makeAndLoadKustTarget(t, th.GetFSys(), "/generator").AccumulateTarget()
|
||||||
|
assert.Error(t, err)
|
||||||
|
assert.Contains(t, err.Error(), "may not add resource with an already registered id: ManifestGenerator.v1.generators.example/ManifestGenerator")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDuplicateExternalTransformersForbidden(t *testing.T) {
|
||||||
|
th := kusttest_test.MakeHarness(t)
|
||||||
|
th.WriteK("/transformer", `
|
||||||
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
|
kind: Kustomization
|
||||||
|
transformers:
|
||||||
|
- |-
|
||||||
|
apiVersion: transformers.example.co/v1
|
||||||
|
kind: ValueAnnotator
|
||||||
|
metadata:
|
||||||
|
name: notImportantHere
|
||||||
|
annotations:
|
||||||
|
config.kubernetes.io/function: |
|
||||||
|
container:
|
||||||
|
image: example.docker.com/my-functions/valueannotator:1.0.0
|
||||||
|
value: 'pass'
|
||||||
|
- |-
|
||||||
|
apiVersion: transformers.example.co/v1
|
||||||
|
kind: ValueAnnotator
|
||||||
|
metadata:
|
||||||
|
name: notImportantHere
|
||||||
|
annotations:
|
||||||
|
config.kubernetes.io/function: |
|
||||||
|
container:
|
||||||
|
image: example.docker.com/my-functions/valueannotator:1.0.0
|
||||||
|
value: 'fail'
|
||||||
|
`)
|
||||||
|
_, err := makeAndLoadKustTarget(t, th.GetFSys(), "/transformer").AccumulateTarget()
|
||||||
|
assert.Error(t, err)
|
||||||
|
assert.Contains(t, err.Error(), "may not add resource with an already registered id: ValueAnnotator.v1.transformers.example.co/notImportantHere")
|
||||||
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ func makeAndLoadKustTarget(
|
|||||||
t *testing.T,
|
t *testing.T,
|
||||||
fSys filesys.FileSystem,
|
fSys filesys.FileSystem,
|
||||||
root string) *target.KustTarget {
|
root string) *target.KustTarget {
|
||||||
|
t.Helper()
|
||||||
kt := makeKustTargetWithRf(t, fSys, root, provider.NewDefaultDepProvider())
|
kt := makeKustTargetWithRf(t, fSys, root, provider.NewDefaultDepProvider())
|
||||||
if err := kt.Load(); err != nil {
|
if err := kt.Load(); err != nil {
|
||||||
t.Fatalf("Unexpected load error %v", err)
|
t.Fatalf("Unexpected load error %v", err)
|
||||||
@@ -32,6 +33,7 @@ func makeKustTargetWithRf(
|
|||||||
fSys filesys.FileSystem,
|
fSys filesys.FileSystem,
|
||||||
root string,
|
root string,
|
||||||
pvd *provider.DepProvider) *target.KustTarget {
|
pvd *provider.DepProvider) *target.KustTarget {
|
||||||
|
t.Helper()
|
||||||
ldr, err := fLdr.NewLoader(fLdr.RestrictionRootOnly, root, fSys)
|
ldr, err := fLdr.NewLoader(fLdr.RestrictionRootOnly, root, fSys)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// Copyright 2022 The Kubernetes Authors.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
package utils
|
package utils
|
||||||
|
|
||||||
import "sigs.k8s.io/kustomize/api/konfig"
|
import "sigs.k8s.io/kustomize/api/konfig"
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// Copyright 2022 The Kubernetes Authors.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
package utils
|
package utils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|||||||
@@ -50,6 +50,16 @@ nameReference:
|
|||||||
kind: Pod
|
kind: Pod
|
||||||
- path: template/spec/volumes/configMap/name
|
- path: template/spec/volumes/configMap/name
|
||||||
kind: PodTemplate
|
kind: PodTemplate
|
||||||
|
- path: template/spec/containers/env/valueFrom/configMapKeyRef/name
|
||||||
|
kind: PodTemplate
|
||||||
|
- path: template/spec/initContainers/env/valueFrom/configMapKeyRef/name
|
||||||
|
kind: PodTemplate
|
||||||
|
- path: template/spec/containers/envFrom/configMapRef/name
|
||||||
|
kind: PodTemplate
|
||||||
|
- path: template/spec/initContainers/envFrom/configMapRef/name
|
||||||
|
kind: PodTemplate
|
||||||
|
- path: template/spec/volumes/projected/sources/configMap/name
|
||||||
|
kind: PodTemplate
|
||||||
- path: spec/template/spec/volumes/configMap/name
|
- path: spec/template/spec/volumes/configMap/name
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
- path: spec/template/spec/containers/env/valueFrom/configMapKeyRef/name
|
- path: spec/template/spec/containers/env/valueFrom/configMapKeyRef/name
|
||||||
@@ -155,6 +165,20 @@ nameReference:
|
|||||||
- path: spec/volumes/projected/sources/secret/name
|
- path: spec/volumes/projected/sources/secret/name
|
||||||
version: v1
|
version: v1
|
||||||
kind: Pod
|
kind: Pod
|
||||||
|
- path: template/spec/volumes/secret/secretName
|
||||||
|
kind: PodTemplate
|
||||||
|
- path: template/spec/containers/env/valueFrom/secretKeyRef/name
|
||||||
|
kind: PodTemplate
|
||||||
|
- path: template/spec/initContainers/env/valueFrom/secretKeyRef/name
|
||||||
|
kind: PodTemplate
|
||||||
|
- path: template/spec/containers/envFrom/secretRef/name
|
||||||
|
kind: PodTemplate
|
||||||
|
- path: template/spec/initContainers/envFrom/secretRef/name
|
||||||
|
kind: PodTemplate
|
||||||
|
- path: template/spec/imagePullSecrets/name
|
||||||
|
kind: PodTemplate
|
||||||
|
- path: template/spec/volumes/projected/sources/secret/name
|
||||||
|
kind: PodTemplate
|
||||||
- path: spec/template/spec/volumes/secret/secretName
|
- path: spec/template/spec/volumes/secret/secretName
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
- path: spec/template/spec/containers/env/valueFrom/secretKeyRef/name
|
- path: spec/template/spec/containers/env/valueFrom/secretKeyRef/name
|
||||||
|
|||||||
@@ -179,9 +179,11 @@ func TestDefaultAbsPluginHomeNoXdgJustHomeDir(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func setenv(t *testing.T, key, value string) {
|
func setenv(t *testing.T, key, value string) {
|
||||||
|
t.Helper()
|
||||||
require.NoError(t, os.Setenv(key, value))
|
require.NoError(t, os.Setenv(key, value))
|
||||||
}
|
}
|
||||||
|
|
||||||
func unsetenv(t *testing.T, key string) {
|
func unsetenv(t *testing.T, key string) {
|
||||||
|
t.Helper()
|
||||||
require.NoError(t, os.Unsetenv(key))
|
require.NoError(t, os.Unsetenv(key))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ package krusty_test
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"sigs.k8s.io/kustomize/api/internal/kusterr"
|
||||||
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
|
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -80,3 +81,35 @@ spec:
|
|||||||
clusterIP: None
|
clusterIP: None
|
||||||
`)
|
`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// test for https://github.com/kubernetes-sigs/kustomize/issues/3812#issuecomment-862339267
|
||||||
|
func TestBasicIO3812(t *testing.T) {
|
||||||
|
th := kusttest_test.MakeHarness(t)
|
||||||
|
th.WriteK(".", `
|
||||||
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
|
kind: Kustomization
|
||||||
|
resources:
|
||||||
|
- service.yaml
|
||||||
|
`)
|
||||||
|
|
||||||
|
th.WriteF("service.yaml", `
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: kapacitor
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: tick-kapacitor
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app.kubernetes.io/name: tick-kapacitor
|
||||||
|
- name: http
|
||||||
|
port: 9092
|
||||||
|
protocol: TCP
|
||||||
|
type: ClusterIP
|
||||||
|
`)
|
||||||
|
|
||||||
|
err := th.RunWithErr(".", th.MakeDefaultOptions())
|
||||||
|
if !kusterr.IsMalformedYAMLError(err) {
|
||||||
|
t.Fatalf("unexpected error: %q", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// Copyright 2022 The Kubernetes Authors.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
package krusty_test
|
package krusty_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|||||||
@@ -551,7 +551,7 @@ components:
|
|||||||
`),
|
`),
|
||||||
},
|
},
|
||||||
runPath: "filesincomponents",
|
runPath: "filesincomponents",
|
||||||
expectedError: "'/filesincomponents/stub.yaml' must be a directory to be a root",
|
expectedError: "'/filesincomponents/stub.yaml' must be a directory so that it can used as a build root",
|
||||||
},
|
},
|
||||||
"invalid-component-api-version": {
|
"invalid-component-api-version": {
|
||||||
input: []FileGen{writeTestBase, writeOverlayProd,
|
input: []FileGen{writeTestBase, writeOverlayProd,
|
||||||
|
|||||||
@@ -460,7 +460,6 @@ metadata:
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestConfigMapGeneratorMergeNamePrefix(t *testing.T) {
|
func TestConfigMapGeneratorMergeNamePrefix(t *testing.T) {
|
||||||
|
|
||||||
th := kusttest_test.MakeHarness(t)
|
th := kusttest_test.MakeHarness(t)
|
||||||
th.WriteK("base", `
|
th.WriteK("base", `
|
||||||
configMapGenerator:
|
configMapGenerator:
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ const container = `{ "image": "my-image", "livenessProbe": { "httpGet" : {"path"
|
|||||||
const patchJsonAddProbe = `[{"op": "replace", "path": "/spec/template/spec/containers/0", "value": ` +
|
const patchJsonAddProbe = `[{"op": "replace", "path": "/spec/template/spec/containers/0", "value": ` +
|
||||||
container + `}]`
|
container + `}]`
|
||||||
|
|
||||||
const patchDnsPolicy = `
|
const patchDNSPolicy = `
|
||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
@@ -44,7 +44,7 @@ spec:
|
|||||||
spec:
|
spec:
|
||||||
dnsPolicy: ClusterFirst
|
dnsPolicy: ClusterFirst
|
||||||
`
|
`
|
||||||
const patchJsonDnsPolicy = `[{"op": "add", "path": "/spec/template/spec/dnsPolicy", "value": "ClusterFirst"}]`
|
const patchJsonDNSPolicy = `[{"op": "add", "path": "/spec/template/spec/dnsPolicy", "value": "ClusterFirst"}]`
|
||||||
|
|
||||||
const patchRestartPolicy = `
|
const patchRestartPolicy = `
|
||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
@@ -96,7 +96,7 @@ resources:
|
|||||||
patchesStrategicMerge:
|
patchesStrategicMerge:
|
||||||
- dep-patch.yaml
|
- dep-patch.yaml
|
||||||
`)
|
`)
|
||||||
th.WriteF("dns/dep-patch.yaml", patchDnsPolicy)
|
th.WriteF("dns/dep-patch.yaml", patchDNSPolicy)
|
||||||
}
|
}
|
||||||
|
|
||||||
func writeRestartOverlay(th kusttest_test.Harness) {
|
func writeRestartOverlay(th kusttest_test.Harness) {
|
||||||
@@ -209,7 +209,7 @@ patchesStrategicMerge:
|
|||||||
- patchRestartPolicy.yaml
|
- patchRestartPolicy.yaml
|
||||||
`)
|
`)
|
||||||
th.WriteF("composite/patchRestartPolicy.yaml", patchRestartPolicy)
|
th.WriteF("composite/patchRestartPolicy.yaml", patchRestartPolicy)
|
||||||
th.WriteF("composite/patchDnsPolicy.yaml", patchDnsPolicy)
|
th.WriteF("composite/patchDnsPolicy.yaml", patchDNSPolicy)
|
||||||
th.WriteF("composite/patchAddProbe.yaml", patchAddProbe)
|
th.WriteF("composite/patchAddProbe.yaml", patchAddProbe)
|
||||||
|
|
||||||
m := th.Run("composite", th.MakeDefaultOptions())
|
m := th.Run("composite", th.MakeDefaultOptions())
|
||||||
@@ -220,7 +220,7 @@ func definePatchDirStructure(th kusttest_test.Harness) {
|
|||||||
writeDeploymentBase(th)
|
writeDeploymentBase(th)
|
||||||
|
|
||||||
th.WriteF("patches/patchRestartPolicy.yaml", patchRestartPolicy)
|
th.WriteF("patches/patchRestartPolicy.yaml", patchRestartPolicy)
|
||||||
th.WriteF("patches/patchDnsPolicy.yaml", patchDnsPolicy)
|
th.WriteF("patches/patchDnsPolicy.yaml", patchDNSPolicy)
|
||||||
th.WriteF("patches/patchAddProbe.yaml", patchAddProbe)
|
th.WriteF("patches/patchAddProbe.yaml", patchAddProbe)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -368,7 +368,7 @@ func TestIssue1251_Plugins_Local(t *testing.T) {
|
|||||||
writeDeploymentBase(th.Harness)
|
writeDeploymentBase(th.Harness)
|
||||||
|
|
||||||
writeJsonTransformerPluginConfig(
|
writeJsonTransformerPluginConfig(
|
||||||
th, "composite", "addDnsPolicy", patchJsonDnsPolicy)
|
th, "composite", "addDnsPolicy", patchJsonDNSPolicy)
|
||||||
writeJsonTransformerPluginConfig(
|
writeJsonTransformerPluginConfig(
|
||||||
th, "composite", "addRestartPolicy", patchJsonRestartPolicy)
|
th, "composite", "addRestartPolicy", patchJsonRestartPolicy)
|
||||||
writeJsonTransformerPluginConfig(
|
writeJsonTransformerPluginConfig(
|
||||||
@@ -417,7 +417,7 @@ resources:
|
|||||||
- addProbeConfig.yaml
|
- addProbeConfig.yaml
|
||||||
`)
|
`)
|
||||||
writeJsonTransformerPluginConfig(
|
writeJsonTransformerPluginConfig(
|
||||||
th, "patches", "addDnsPolicy", patchJsonDnsPolicy)
|
th, "patches", "addDnsPolicy", patchJsonDNSPolicy)
|
||||||
writeJsonTransformerPluginConfig(
|
writeJsonTransformerPluginConfig(
|
||||||
th, "patches", "addRestartPolicy", patchJsonRestartPolicy)
|
th, "patches", "addRestartPolicy", patchJsonRestartPolicy)
|
||||||
writeJsonTransformerPluginConfig(
|
writeJsonTransformerPluginConfig(
|
||||||
@@ -441,7 +441,7 @@ resources:
|
|||||||
- addDnsPolicyConfig.yaml
|
- addDnsPolicyConfig.yaml
|
||||||
`)
|
`)
|
||||||
writeJsonTransformerPluginConfig(
|
writeJsonTransformerPluginConfig(
|
||||||
th, "patches/addDnsPolicy", "addDnsPolicy", patchJsonDnsPolicy)
|
th, "patches/addDnsPolicy", "addDnsPolicy", patchJsonDNSPolicy)
|
||||||
|
|
||||||
th.WriteK("patches/addRestartPolicy", `
|
th.WriteK("patches/addRestartPolicy", `
|
||||||
resources:
|
resources:
|
||||||
|
|||||||
@@ -82,21 +82,19 @@ metadata:
|
|||||||
secret := findSecret(m, "")
|
secret := findSecret(m, "")
|
||||||
if secret == nil {
|
if secret == nil {
|
||||||
t.Errorf("Expected to find a Secret")
|
t.Errorf("Expected to find a Secret")
|
||||||
}
|
} else if secret.GetName() != "foo-secret-bar-82c2g5f8f6" {
|
||||||
if secret.GetName() != "foo-secret-bar-82c2g5f8f6" {
|
|
||||||
t.Errorf("unexpected secret resource name: %s", secret.GetName())
|
t.Errorf("unexpected secret resource name: %s", secret.GetName())
|
||||||
}
|
}
|
||||||
|
|
||||||
th.WriteK("/whatever",
|
th.WriteK("/whatever",
|
||||||
strings.Replace(kustomizationContent,
|
strings.ReplaceAll(kustomizationContent,
|
||||||
"disableNameSuffixHash: false",
|
"disableNameSuffixHash: false",
|
||||||
"disableNameSuffixHash: true", -1))
|
"disableNameSuffixHash: true"))
|
||||||
m = th.Run("/whatever", th.MakeDefaultOptions())
|
m = th.Run("/whatever", th.MakeDefaultOptions())
|
||||||
secret = findSecret(m, "")
|
secret = findSecret(m, "")
|
||||||
if secret == nil {
|
if secret == nil {
|
||||||
t.Errorf("Expected to find a Secret")
|
t.Errorf("Expected to find a Secret")
|
||||||
}
|
} else if secret.GetName() != "foo-secret-bar" { // No hash at end.
|
||||||
if secret.GetName() != "foo-secret-bar" { // No hash at end.
|
|
||||||
t.Errorf("unexpected secret resource name: %s", secret.GetName())
|
t.Errorf("unexpected secret resource name: %s", secret.GetName())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -131,16 +129,14 @@ secretGenerator:
|
|||||||
secret := findSecret(m, "nohash")
|
secret := findSecret(m, "nohash")
|
||||||
if secret == nil {
|
if secret == nil {
|
||||||
t.Errorf("Expected to find a Secret")
|
t.Errorf("Expected to find a Secret")
|
||||||
}
|
} else if secret.GetName() != "nohash" {
|
||||||
if secret.GetName() != "nohash" {
|
|
||||||
t.Errorf("unexpected secret resource name: %s", secret.GetName())
|
t.Errorf("unexpected secret resource name: %s", secret.GetName())
|
||||||
}
|
}
|
||||||
|
|
||||||
secret = findSecret(m, "yeshash")
|
secret = findSecret(m, "yeshash")
|
||||||
if secret == nil {
|
if secret == nil {
|
||||||
t.Errorf("Expected to find a Secret")
|
t.Errorf("Expected to find a Secret")
|
||||||
}
|
} else if secret.GetName() != "yeshash-82c2g5f8f6" {
|
||||||
if secret.GetName() != "yeshash-82c2g5f8f6" {
|
|
||||||
t.Errorf("unexpected secret resource name: %s", secret.GetName())
|
t.Errorf("unexpected secret resource name: %s", secret.GetName())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// Copyright 2022 The Kubernetes Authors.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
package krusty_test
|
package krusty_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// Copyright 2022 The Kubernetes Authors.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
package krusty_test
|
package krusty_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -7,6 +10,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
. "sigs.k8s.io/kustomize/api/krusty"
|
||||||
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
|
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
|
||||||
"sigs.k8s.io/kustomize/kyaml/filesys"
|
"sigs.k8s.io/kustomize/kyaml/filesys"
|
||||||
)
|
)
|
||||||
@@ -214,6 +218,7 @@ spec:
|
|||||||
}
|
}
|
||||||
|
|
||||||
func skipIfNoDocker(t *testing.T) {
|
func skipIfNoDocker(t *testing.T) {
|
||||||
|
t.Helper()
|
||||||
if _, err := exec.LookPath("docker"); err != nil {
|
if _, err := exec.LookPath("docker"); err != nil {
|
||||||
t.Skip("skipping because docker binary wasn't found in PATH")
|
t.Skip("skipping because docker binary wasn't found in PATH")
|
||||||
}
|
}
|
||||||
@@ -531,30 +536,33 @@ spec:
|
|||||||
|
|
||||||
func TestFnContainerTransformerWithConfig(t *testing.T) {
|
func TestFnContainerTransformerWithConfig(t *testing.T) {
|
||||||
skipIfNoDocker(t)
|
skipIfNoDocker(t)
|
||||||
|
|
||||||
// Function plugins should not need the env setup done by MakeEnhancedHarness
|
|
||||||
th := kusttest_test.MakeHarness(t)
|
th := kusttest_test.MakeHarness(t)
|
||||||
|
o := th.MakeOptionsPluginsEnabled()
|
||||||
th.WriteK(".", `
|
fSys := filesys.MakeFsOnDisk()
|
||||||
|
b := MakeKustomizer(&o)
|
||||||
|
tmpDir, err := filesys.NewTmpConfirmedDir()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NoError(t, fSys.WriteFile(filepath.Join(tmpDir.String(), "kustomization.yaml"), []byte(`
|
||||||
resources:
|
resources:
|
||||||
- data1.yaml
|
- data1.yaml
|
||||||
- data2.yaml
|
- data2.yaml
|
||||||
transformers:
|
transformers:
|
||||||
- label_namespace.yaml
|
- label_namespace.yaml
|
||||||
`)
|
`)))
|
||||||
|
assert.NoError(t, fSys.WriteFile(filepath.Join(tmpDir.String(), "data1.yaml"), []byte(`
|
||||||
th.WriteF("data1.yaml", `apiVersion: v1
|
apiVersion: v1
|
||||||
kind: Namespace
|
kind: Namespace
|
||||||
metadata:
|
metadata:
|
||||||
name: my-namespace
|
name: my-namespace
|
||||||
`)
|
`)))
|
||||||
th.WriteF("data2.yaml", `apiVersion: v1
|
assert.NoError(t, fSys.WriteFile(filepath.Join(tmpDir.String(), "data2.yaml"), []byte(`
|
||||||
|
apiVersion: v1
|
||||||
kind: Namespace
|
kind: Namespace
|
||||||
metadata:
|
metadata:
|
||||||
name: another-namespace
|
name: another-namespace
|
||||||
`)
|
`)))
|
||||||
|
assert.NoError(t, fSys.WriteFile(filepath.Join(tmpDir.String(), "label_namespace.yaml"), []byte(`
|
||||||
th.WriteF("label_namespace.yaml", `apiVersion: v1
|
apiVersion: v1
|
||||||
kind: ConfigMap
|
kind: ConfigMap
|
||||||
metadata:
|
metadata:
|
||||||
name: label_namespace
|
name: label_namespace
|
||||||
@@ -565,11 +573,14 @@ metadata:
|
|||||||
data:
|
data:
|
||||||
label_name: my-ns-name
|
label_name: my-ns-name
|
||||||
label_value: function-test
|
label_value: function-test
|
||||||
`)
|
`)))
|
||||||
|
m, err := b.Run(
|
||||||
m := th.Run(".", th.MakeOptionsPluginsEnabled())
|
fSys,
|
||||||
th.AssertActualEqualsExpected(m, `
|
tmpDir.String())
|
||||||
apiVersion: v1
|
assert.NoError(t, err)
|
||||||
|
actual, err := m.AsYaml()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, `apiVersion: v1
|
||||||
kind: Namespace
|
kind: Namespace
|
||||||
metadata:
|
metadata:
|
||||||
labels:
|
labels:
|
||||||
@@ -582,24 +593,22 @@ metadata:
|
|||||||
labels:
|
labels:
|
||||||
my-ns-name: function-test
|
my-ns-name: function-test
|
||||||
name: another-namespace
|
name: another-namespace
|
||||||
`)
|
`, string(actual))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFnContainerEnvVars(t *testing.T) {
|
func TestFnContainerEnvVars(t *testing.T) {
|
||||||
skipIfNoDocker(t)
|
skipIfNoDocker(t)
|
||||||
|
|
||||||
// Function plugins should not need the env setup done by MakeEnhancedHarness
|
|
||||||
th := kusttest_test.MakeHarness(t)
|
th := kusttest_test.MakeHarness(t)
|
||||||
|
o := th.MakeOptionsPluginsEnabled()
|
||||||
th.WriteK(".", `
|
fSys := filesys.MakeFsOnDisk()
|
||||||
|
b := MakeKustomizer(&o)
|
||||||
|
tmpDir, err := filesys.NewTmpConfirmedDir()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NoError(t, fSys.WriteFile(filepath.Join(tmpDir.String(), "kustomization.yaml"), []byte(`
|
||||||
generators:
|
generators:
|
||||||
- gener.yaml
|
- gener.yaml
|
||||||
`)
|
`)))
|
||||||
|
assert.NoError(t, fSys.WriteFile(filepath.Join(tmpDir.String(), "gener.yaml"), []byte(`
|
||||||
// TODO: cheange image to gcr.io/kpt-functions/templater:stable
|
|
||||||
// when https://github.com/GoogleContainerTools/kpt-functions-catalog/pull/103
|
|
||||||
// is merged
|
|
||||||
th.WriteF("gener.yaml", `
|
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: ConfigMap
|
kind: ConfigMap
|
||||||
metadata:
|
metadata:
|
||||||
@@ -618,14 +627,176 @@ data:
|
|||||||
name: env
|
name: env
|
||||||
data:
|
data:
|
||||||
value: '{{ env "TESTTEMPLATE" }}'
|
value: '{{ env "TESTTEMPLATE" }}'
|
||||||
`)
|
`)))
|
||||||
m := th.Run(".", th.MakeOptionsPluginsEnabled())
|
m, err := b.Run(
|
||||||
th.AssertActualEqualsExpected(m, `
|
fSys,
|
||||||
apiVersion: v1
|
tmpDir.String())
|
||||||
|
assert.NoError(t, err)
|
||||||
|
actual, err := m.AsYaml()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, `apiVersion: v1
|
||||||
data:
|
data:
|
||||||
value: value
|
value: value
|
||||||
kind: ConfigMap
|
kind: ConfigMap
|
||||||
metadata:
|
metadata:
|
||||||
name: env
|
name: env
|
||||||
`)
|
`, string(actual))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFnContainerFnMounts(t *testing.T) {
|
||||||
|
skipIfNoDocker(t)
|
||||||
|
th := kusttest_test.MakeHarness(t)
|
||||||
|
o := th.MakeOptionsPluginsEnabled()
|
||||||
|
fSys := filesys.MakeFsOnDisk()
|
||||||
|
b := MakeKustomizer(&o)
|
||||||
|
tmpDir, err := filesys.NewTmpConfirmedDir()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NoError(t, fSys.WriteFile(filepath.Join(tmpDir.String(), "kustomization.yaml"), []byte(`
|
||||||
|
generators:
|
||||||
|
- gener.yaml
|
||||||
|
`)))
|
||||||
|
assert.NoError(t, fSys.WriteFile(filepath.Join(tmpDir.String(), "gener.yaml"), []byte(`
|
||||||
|
apiVersion: v1alpha1
|
||||||
|
kind: RenderHelmChart
|
||||||
|
metadata:
|
||||||
|
name: demo
|
||||||
|
annotations:
|
||||||
|
config.kubernetes.io/function: |
|
||||||
|
container:
|
||||||
|
image: gcr.io/kpt-fn/render-helm-chart:v0.1.0
|
||||||
|
mounts:
|
||||||
|
- type: "bind"
|
||||||
|
src: "./charts"
|
||||||
|
dst: "/tmp/charts"
|
||||||
|
helmCharts:
|
||||||
|
- name: helloworld-chart
|
||||||
|
releaseName: test
|
||||||
|
valuesFile: /tmp/charts/helloworld-values/values.yaml
|
||||||
|
`)))
|
||||||
|
assert.NoError(t, fSys.MkdirAll(filepath.Join(tmpDir.String(), "charts", "helloworld-chart", "templates")))
|
||||||
|
assert.NoError(t, fSys.MkdirAll(filepath.Join(tmpDir.String(), "charts", "helloworld-values")))
|
||||||
|
assert.NoError(t, fSys.WriteFile(filepath.Join(tmpDir.String(), "charts", "helloworld-chart", "Chart.yaml"), []byte(`
|
||||||
|
apiVersion: v2
|
||||||
|
name: helloworld-chart
|
||||||
|
description: A Helm chart for Kubernetes
|
||||||
|
type: application
|
||||||
|
version: 0.1.0
|
||||||
|
appVersion: 1.16.0
|
||||||
|
`)))
|
||||||
|
assert.NoError(t, fSys.WriteFile(filepath.Join(tmpDir.String(), "charts", "helloworld-chart", "templates", "deployment.yaml"), []byte(`
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: name
|
||||||
|
spec:
|
||||||
|
replicas: {{ .Values.replicaCount }}
|
||||||
|
`)))
|
||||||
|
assert.NoError(t, fSys.WriteFile(filepath.Join(tmpDir.String(), "charts", "helloworld-values", "values.yaml"), []byte(`
|
||||||
|
replicaCount: 5
|
||||||
|
`)))
|
||||||
|
m, err := b.Run(
|
||||||
|
fSys,
|
||||||
|
tmpDir.String())
|
||||||
|
assert.NoError(t, err)
|
||||||
|
actual, err := m.AsYaml()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.Equal(t, `apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: name
|
||||||
|
spec:
|
||||||
|
replicas: 5
|
||||||
|
`, string(actual))
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFnContainerMountsLoadRestrictions_absolute(t *testing.T) {
|
||||||
|
skipIfNoDocker(t)
|
||||||
|
th := kusttest_test.MakeHarness(t)
|
||||||
|
o := th.MakeOptionsPluginsEnabled()
|
||||||
|
fSys := filesys.MakeFsOnDisk()
|
||||||
|
b := MakeKustomizer(&o)
|
||||||
|
tmpDir, err := filesys.NewTmpConfirmedDir()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NoError(t, fSys.WriteFile(filepath.Join(tmpDir.String(), "kustomization.yaml"), []byte(`
|
||||||
|
generators:
|
||||||
|
- |-
|
||||||
|
apiVersion: v1alpha1
|
||||||
|
kind: RenderHelmChart
|
||||||
|
metadata:
|
||||||
|
name: demo
|
||||||
|
annotations:
|
||||||
|
config.kubernetes.io/function: |
|
||||||
|
container:
|
||||||
|
image: gcr.io/kpt-fn/render-helm-chart:v0.1.0
|
||||||
|
mounts:
|
||||||
|
- type: "bind"
|
||||||
|
src: "/tmp/dir"
|
||||||
|
dst: "/tmp/charts"
|
||||||
|
`)))
|
||||||
|
_, err = b.Run(
|
||||||
|
fSys,
|
||||||
|
tmpDir.String())
|
||||||
|
assert.Error(t, err)
|
||||||
|
assert.Contains(t, err.Error(), "loading generator plugins: plugin RenderHelmChart."+
|
||||||
|
"v1alpha1.[noGrp]/demo.[noNs] with mount path '/tmp/dir' is not permitted; mount paths must"+
|
||||||
|
" be relative to the current kustomization directory")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFnContainerMountsLoadRestrictions_outsideCurrentDir(t *testing.T) {
|
||||||
|
skipIfNoDocker(t)
|
||||||
|
th := kusttest_test.MakeHarness(t)
|
||||||
|
o := th.MakeOptionsPluginsEnabled()
|
||||||
|
fSys := filesys.MakeFsOnDisk()
|
||||||
|
b := MakeKustomizer(&o)
|
||||||
|
tmpDir, err := filesys.NewTmpConfirmedDir()
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NoError(t, fSys.WriteFile(filepath.Join(tmpDir.String(), "kustomization.yaml"), []byte(`
|
||||||
|
generators:
|
||||||
|
- |-
|
||||||
|
apiVersion: v1alpha1
|
||||||
|
kind: RenderHelmChart
|
||||||
|
metadata:
|
||||||
|
name: demo
|
||||||
|
annotations:
|
||||||
|
config.kubernetes.io/function: |
|
||||||
|
container:
|
||||||
|
image: gcr.io/kpt-fn/render-helm-chart:v0.1.0
|
||||||
|
mounts:
|
||||||
|
- type: "bind"
|
||||||
|
src: "./tmp/../../dir"
|
||||||
|
dst: "/tmp/charts"
|
||||||
|
`)))
|
||||||
|
_, err = b.Run(
|
||||||
|
fSys,
|
||||||
|
tmpDir.String())
|
||||||
|
assert.Error(t, err)
|
||||||
|
assert.Contains(t, err.Error(), "loading generator plugins: plugin RenderHelmChart."+
|
||||||
|
"v1alpha1.[noGrp]/demo.[noNs] with mount path './tmp/../../dir' is not permitted; mount paths must "+
|
||||||
|
"be under the current kustomization directory")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFnContainerMountsLoadRestrictions_root(t *testing.T) {
|
||||||
|
skipIfNoDocker(t)
|
||||||
|
th := kusttest_test.MakeHarness(t)
|
||||||
|
|
||||||
|
th.WriteK(".", `
|
||||||
|
generators:
|
||||||
|
- gener.yaml
|
||||||
|
`)
|
||||||
|
// Create generator config
|
||||||
|
th.WriteF("gener.yaml", `
|
||||||
|
apiVersion: examples.config.kubernetes.io/v1beta1
|
||||||
|
kind: CockroachDB
|
||||||
|
metadata:
|
||||||
|
name: demo
|
||||||
|
annotations:
|
||||||
|
config.kubernetes.io/function: |
|
||||||
|
container:
|
||||||
|
image: gcr.io/kustomize-functions/example-cockroachdb:v0.1.0
|
||||||
|
spec:
|
||||||
|
replicas: 3
|
||||||
|
`)
|
||||||
|
err := th.RunWithErr(".", th.MakeOptionsPluginsEnabled())
|
||||||
|
assert.Error(t, err)
|
||||||
|
assert.EqualError(t, err, "couldn't execute function: root working directory '/' not allowed")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// Copyright 2022 The Kubernetes Authors.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
package krusty_test
|
package krusty_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|||||||
@@ -91,3 +91,72 @@ spec:
|
|||||||
c: d
|
c: d
|
||||||
`)
|
`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestKustomizationLabelsInTemplate(t *testing.T) {
|
||||||
|
th := kusttest_test.MakeHarness(t)
|
||||||
|
th.WriteF("app/deployment.yaml", `
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/component: a
|
||||||
|
app.kubernetes.io/instance: b
|
||||||
|
app.kubernetes.io/name: c
|
||||||
|
app.kubernetes.io/part-of: d
|
||||||
|
name: deployment
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/component: a
|
||||||
|
app.kubernetes.io/instance: b
|
||||||
|
app.kubernetes.io/name: c
|
||||||
|
app.kubernetes.io/part-of: d
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/component: a
|
||||||
|
app.kubernetes.io/instance: b
|
||||||
|
app.kubernetes.io/name: c
|
||||||
|
app.kubernetes.io/part-of: d
|
||||||
|
`)
|
||||||
|
th.WriteK("/app", `
|
||||||
|
resources:
|
||||||
|
- deployment.yaml
|
||||||
|
|
||||||
|
labels:
|
||||||
|
- pairs:
|
||||||
|
foo: bar
|
||||||
|
includeSelectors: false
|
||||||
|
includeTemplates: true
|
||||||
|
`)
|
||||||
|
m := th.Run("/app", th.MakeDefaultOptions())
|
||||||
|
th.AssertActualEqualsExpected(m, `
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/component: a
|
||||||
|
app.kubernetes.io/instance: b
|
||||||
|
app.kubernetes.io/name: c
|
||||||
|
app.kubernetes.io/part-of: d
|
||||||
|
foo: bar
|
||||||
|
name: deployment
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/component: a
|
||||||
|
app.kubernetes.io/instance: b
|
||||||
|
app.kubernetes.io/name: c
|
||||||
|
app.kubernetes.io/part-of: d
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/component: a
|
||||||
|
app.kubernetes.io/instance: b
|
||||||
|
app.kubernetes.io/name: c
|
||||||
|
app.kubernetes.io/part-of: d
|
||||||
|
foo: bar
|
||||||
|
`)
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// Copyright 2022 The Kubernetes Authors.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
package krusty_test
|
package krusty_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// Copyright 2022 The Kubernetes Authors.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
package krusty_test
|
package krusty_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// Copyright 2022 The Kubernetes Authors.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
package krusty_test
|
package krusty_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ package krusty
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"path/filepath"
|
|
||||||
|
|
||||||
"sigs.k8s.io/kustomize/api/internal/builtins"
|
"sigs.k8s.io/kustomize/api/internal/builtins"
|
||||||
pLdr "sigs.k8s.io/kustomize/api/internal/plugins/loader"
|
pLdr "sigs.k8s.io/kustomize/api/internal/plugins/loader"
|
||||||
@@ -76,7 +75,7 @@ func (b *Kustomizer) Run(
|
|||||||
}
|
}
|
||||||
var bytes []byte
|
var bytes []byte
|
||||||
if openApiPath, exists := kt.Kustomization().OpenAPI["path"]; exists {
|
if openApiPath, exists := kt.Kustomization().OpenAPI["path"]; exists {
|
||||||
bytes, err = ldr.Load(filepath.Join(ldr.Root(), openApiPath))
|
bytes, err = ldr.Load(openApiPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// Copyright 2022 The Kubernetes Authors.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
package krusty_test
|
package krusty_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// Copyright 2022 The Kubernetes Authors.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
package krusty_test
|
package krusty_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// Copyright 2022 The Kubernetes Authors.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
package krusty_test
|
package krusty_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|||||||
@@ -692,6 +692,7 @@ resources:
|
|||||||
th.AssertActualEqualsExpected(m, namespaceNeedInVarExpectedOutput)
|
th.AssertActualEqualsExpected(m, namespaceNeedInVarExpectedOutput)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// nolint:gosec
|
||||||
const namespaceNeedInVarMyAppWithNamespace string = `
|
const namespaceNeedInVarMyAppWithNamespace string = `
|
||||||
resources:
|
resources:
|
||||||
- elasticsearch-dev-service.yaml
|
- elasticsearch-dev-service.yaml
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// Copyright 2022 The Kubernetes Authors.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
package krusty_test
|
package krusty_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|||||||
@@ -1,455 +0,0 @@
|
|||||||
// Copyright 2019 The Kubernetes Authors.
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
package krusty_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
|
|
||||||
"sigs.k8s.io/kustomize/kyaml/openapi"
|
|
||||||
)
|
|
||||||
|
|
||||||
func writeTestSchema(th kusttest_test.Harness, filepath string) {
|
|
||||||
bytes, _ := ioutil.ReadFile("testdata/customschema.json")
|
|
||||||
th.WriteF(filepath+"mycrd_schema.json", string(bytes))
|
|
||||||
}
|
|
||||||
|
|
||||||
func writeTestSchemaYaml(th kusttest_test.Harness, filepath string) {
|
|
||||||
bytes, _ := ioutil.ReadFile("testdata/customschema.yaml")
|
|
||||||
th.WriteF(filepath+"mycrd_schema.yaml", string(bytes))
|
|
||||||
}
|
|
||||||
|
|
||||||
func writeCustomResource(th kusttest_test.Harness, filepath string) {
|
|
||||||
th.WriteF(filepath, `
|
|
||||||
apiVersion: example.com/v1alpha1
|
|
||||||
kind: MyCRD
|
|
||||||
metadata:
|
|
||||||
name: service
|
|
||||||
spec:
|
|
||||||
template:
|
|
||||||
spec:
|
|
||||||
containers:
|
|
||||||
- name: server
|
|
||||||
image: server
|
|
||||||
command: example
|
|
||||||
ports:
|
|
||||||
- name: grpc
|
|
||||||
protocol: TCP
|
|
||||||
containerPort: 8080
|
|
||||||
`)
|
|
||||||
}
|
|
||||||
|
|
||||||
func writeOtherCustomResource(th kusttest_test.Harness, filepath string) {
|
|
||||||
th.WriteF(filepath, `
|
|
||||||
apiVersion: v1alpha1
|
|
||||||
kind: MyCRD
|
|
||||||
metadata:
|
|
||||||
name: service
|
|
||||||
spec:
|
|
||||||
template:
|
|
||||||
spec:
|
|
||||||
containers:
|
|
||||||
- name: server
|
|
||||||
image: server
|
|
||||||
command: example
|
|
||||||
ports:
|
|
||||||
- name: grpc
|
|
||||||
protocol: TCP
|
|
||||||
containerPort: 8080
|
|
||||||
`)
|
|
||||||
}
|
|
||||||
|
|
||||||
func writeTestComponentWithCustomSchema(th kusttest_test.Harness) {
|
|
||||||
writeTestSchema(th, "comp/")
|
|
||||||
openapi.ResetOpenAPI()
|
|
||||||
th.WriteC("comp", `
|
|
||||||
openapi:
|
|
||||||
path: mycrd_schema.json
|
|
||||||
`)
|
|
||||||
th.WriteF("comp/stub.yaml", `
|
|
||||||
apiVersion: v1
|
|
||||||
kind: Deployment
|
|
||||||
metadata:
|
|
||||||
name: stub
|
|
||||||
spec:
|
|
||||||
replicas: 1
|
|
||||||
`)
|
|
||||||
}
|
|
||||||
|
|
||||||
const customSchemaPatch = `
|
|
||||||
patchesStrategicMerge:
|
|
||||||
- |-
|
|
||||||
apiVersion: example.com/v1alpha1
|
|
||||||
kind: MyCRD
|
|
||||||
metadata:
|
|
||||||
name: service
|
|
||||||
spec:
|
|
||||||
template:
|
|
||||||
spec:
|
|
||||||
containers:
|
|
||||||
- name: server
|
|
||||||
image: nginx
|
|
||||||
`
|
|
||||||
|
|
||||||
const customSchemaPatchMultipleGvks = `
|
|
||||||
patchesStrategicMerge:
|
|
||||||
- |-
|
|
||||||
apiVersion: example.com/v1alpha1
|
|
||||||
kind: MyCRD
|
|
||||||
metadata:
|
|
||||||
name: service
|
|
||||||
spec:
|
|
||||||
template:
|
|
||||||
spec:
|
|
||||||
containers:
|
|
||||||
- name: server
|
|
||||||
image: nginx
|
|
||||||
- |-
|
|
||||||
apiVersion: v1alpha1
|
|
||||||
kind: MyCRD
|
|
||||||
metadata:
|
|
||||||
name: service
|
|
||||||
spec:
|
|
||||||
template:
|
|
||||||
spec:
|
|
||||||
containers:
|
|
||||||
- name: server
|
|
||||||
image: nginx
|
|
||||||
`
|
|
||||||
|
|
||||||
const patchedCustomResource = `
|
|
||||||
apiVersion: example.com/v1alpha1
|
|
||||||
kind: MyCRD
|
|
||||||
metadata:
|
|
||||||
name: service
|
|
||||||
spec:
|
|
||||||
template:
|
|
||||||
spec:
|
|
||||||
containers:
|
|
||||||
- command: example
|
|
||||||
image: nginx
|
|
||||||
name: server
|
|
||||||
ports:
|
|
||||||
- containerPort: 8080
|
|
||||||
name: grpc
|
|
||||||
protocol: TCP
|
|
||||||
`
|
|
||||||
|
|
||||||
// Test for issue #2825
|
|
||||||
func TestCustomOpenApiFieldBasicUsage(t *testing.T) {
|
|
||||||
th := kusttest_test.MakeHarness(t)
|
|
||||||
th.WriteK(".", `
|
|
||||||
resources:
|
|
||||||
- mycrd.yaml
|
|
||||||
openapi:
|
|
||||||
path: mycrd_schema.json
|
|
||||||
`+customSchemaPatch)
|
|
||||||
writeCustomResource(th, "mycrd.yaml")
|
|
||||||
writeTestSchema(th, "./")
|
|
||||||
openapi.ResetOpenAPI()
|
|
||||||
m := th.Run(".", th.MakeDefaultOptions())
|
|
||||||
th.AssertActualEqualsExpected(m, patchedCustomResource)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCustomOpenApiFieldWithTwoGvks(t *testing.T) {
|
|
||||||
th := kusttest_test.MakeHarness(t)
|
|
||||||
th.WriteK(".", `
|
|
||||||
resources:
|
|
||||||
- mycrd.yaml
|
|
||||||
- myothercrd.yaml
|
|
||||||
openapi:
|
|
||||||
path: mycrd_schema.json
|
|
||||||
`+customSchemaPatchMultipleGvks)
|
|
||||||
writeCustomResource(th, "mycrd.yaml")
|
|
||||||
writeOtherCustomResource(th, "myothercrd.yaml")
|
|
||||||
writeTestSchema(th, "./")
|
|
||||||
openapi.ResetOpenAPI()
|
|
||||||
m := th.Run(".", th.MakeDefaultOptions())
|
|
||||||
th.AssertActualEqualsExpected(m, `apiVersion: example.com/v1alpha1
|
|
||||||
kind: MyCRD
|
|
||||||
metadata:
|
|
||||||
name: service
|
|
||||||
spec:
|
|
||||||
template:
|
|
||||||
spec:
|
|
||||||
containers:
|
|
||||||
- command: example
|
|
||||||
image: nginx
|
|
||||||
name: server
|
|
||||||
ports:
|
|
||||||
- containerPort: 8080
|
|
||||||
name: grpc
|
|
||||||
protocol: TCP
|
|
||||||
---
|
|
||||||
apiVersion: v1alpha1
|
|
||||||
kind: MyCRD
|
|
||||||
metadata:
|
|
||||||
name: service
|
|
||||||
spec:
|
|
||||||
template:
|
|
||||||
spec:
|
|
||||||
containers:
|
|
||||||
- command: example
|
|
||||||
image: nginx
|
|
||||||
name: server
|
|
||||||
ports:
|
|
||||||
- containerPort: 8080
|
|
||||||
name: grpc
|
|
||||||
protocol: TCP
|
|
||||||
`)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCustomOpenApiFieldYaml(t *testing.T) {
|
|
||||||
th := kusttest_test.MakeHarness(t)
|
|
||||||
th.WriteK(".", `
|
|
||||||
resources:
|
|
||||||
- mycrd.yaml
|
|
||||||
openapi:
|
|
||||||
path: mycrd_schema.yaml
|
|
||||||
`+customSchemaPatch)
|
|
||||||
writeCustomResource(th, "mycrd.yaml")
|
|
||||||
writeTestSchemaYaml(th, "./")
|
|
||||||
openapi.ResetOpenAPI()
|
|
||||||
m := th.Run(".", th.MakeDefaultOptions())
|
|
||||||
th.AssertActualEqualsExpected(m, patchedCustomResource)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Error if user tries to specify both builtin version
|
|
||||||
// and custom schema
|
|
||||||
func TestCustomOpenApiFieldBothPathAndVersion(t *testing.T) {
|
|
||||||
th := kusttest_test.MakeHarness(t)
|
|
||||||
th.WriteK(".", `
|
|
||||||
resources:
|
|
||||||
- mycrd.yaml
|
|
||||||
openapi:
|
|
||||||
version: v1.21.2
|
|
||||||
path: mycrd_schema.json
|
|
||||||
`+customSchemaPatch)
|
|
||||||
writeCustomResource(th, "mycrd.yaml")
|
|
||||||
writeTestSchema(th, "./")
|
|
||||||
openapi.ResetOpenAPI()
|
|
||||||
err := th.RunWithErr(".", th.MakeDefaultOptions())
|
|
||||||
assert.Error(t, err)
|
|
||||||
assert.Equal(t,
|
|
||||||
"builtin version and custom schema provided, cannot use both",
|
|
||||||
err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test for if the filepath specified is not found
|
|
||||||
func TestCustomOpenApiFieldFileNotFound(t *testing.T) {
|
|
||||||
th := kusttest_test.MakeHarness(t)
|
|
||||||
th.WriteK(".", `
|
|
||||||
resources:
|
|
||||||
- mycrd.yaml
|
|
||||||
openapi:
|
|
||||||
path: mycrd_schema.json
|
|
||||||
`+customSchemaPatch)
|
|
||||||
writeCustomResource(th, "mycrd.yaml")
|
|
||||||
openapi.ResetOpenAPI()
|
|
||||||
err := th.RunWithErr(".", th.MakeDefaultOptions())
|
|
||||||
assert.Error(t, err)
|
|
||||||
assert.Equal(t,
|
|
||||||
"'/mycrd_schema.json' doesn't exist",
|
|
||||||
err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCustomOpenApiFieldFromBase(t *testing.T) {
|
|
||||||
th := kusttest_test.MakeHarness(t)
|
|
||||||
th.WriteK("base", `
|
|
||||||
resources:
|
|
||||||
- mycrd.yaml
|
|
||||||
openapi:
|
|
||||||
path: mycrd_schema.json
|
|
||||||
`)
|
|
||||||
th.WriteK("overlay", `
|
|
||||||
resources:
|
|
||||||
- ../base
|
|
||||||
`+customSchemaPatch)
|
|
||||||
writeCustomResource(th, "base/mycrd.yaml")
|
|
||||||
writeTestSchema(th, "base/")
|
|
||||||
openapi.ResetOpenAPI()
|
|
||||||
m := th.Run("overlay", th.MakeDefaultOptions())
|
|
||||||
th.AssertActualEqualsExpected(m, patchedCustomResource)
|
|
||||||
assert.Equal(t, "using custom schema from file provided",
|
|
||||||
openapi.GetSchemaVersion())
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCustomOpenApiFieldFromOverlay(t *testing.T) {
|
|
||||||
th := kusttest_test.MakeHarness(t)
|
|
||||||
th.WriteK("base", `
|
|
||||||
resources:
|
|
||||||
- mycrd.yaml
|
|
||||||
`)
|
|
||||||
th.WriteK("overlay", `
|
|
||||||
resources:
|
|
||||||
- ../base
|
|
||||||
openapi:
|
|
||||||
path: mycrd_schema.json
|
|
||||||
`+customSchemaPatch)
|
|
||||||
writeCustomResource(th, "base/mycrd.yaml")
|
|
||||||
writeTestSchema(th, "overlay/")
|
|
||||||
openapi.ResetOpenAPI()
|
|
||||||
m := th.Run("overlay", th.MakeDefaultOptions())
|
|
||||||
th.AssertActualEqualsExpected(m, patchedCustomResource)
|
|
||||||
assert.Equal(t, "using custom schema from file provided",
|
|
||||||
openapi.GetSchemaVersion())
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCustomOpenApiFieldOverlayTakesPrecedence(t *testing.T) {
|
|
||||||
th := kusttest_test.MakeHarness(t)
|
|
||||||
openapi.ResetOpenAPI()
|
|
||||||
th.WriteK("base", `
|
|
||||||
resources:
|
|
||||||
- mycrd.yaml
|
|
||||||
openapi:
|
|
||||||
path: mycrd_schema.json
|
|
||||||
`)
|
|
||||||
th.WriteK("overlay", `
|
|
||||||
resources:
|
|
||||||
- ../base
|
|
||||||
openapi:
|
|
||||||
version: v1.21.2
|
|
||||||
`+customSchemaPatch)
|
|
||||||
writeCustomResource(th, "base/mycrd.yaml")
|
|
||||||
writeTestSchema(th, "base/")
|
|
||||||
openapi.ResetOpenAPI()
|
|
||||||
m := th.Run("overlay", th.MakeDefaultOptions())
|
|
||||||
th.AssertActualEqualsExpected(m, `
|
|
||||||
apiVersion: example.com/v1alpha1
|
|
||||||
kind: MyCRD
|
|
||||||
metadata:
|
|
||||||
name: service
|
|
||||||
spec:
|
|
||||||
template:
|
|
||||||
spec:
|
|
||||||
containers:
|
|
||||||
- image: nginx
|
|
||||||
name: server
|
|
||||||
`)
|
|
||||||
assert.Equal(t, "v1212", openapi.GetSchemaVersion())
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestCustomOpenAPIFieldFromComponent(t *testing.T) {
|
|
||||||
input := []FileGen{
|
|
||||||
writeTestBase,
|
|
||||||
writeTestComponentWithCustomSchema,
|
|
||||||
writeOverlayProd}
|
|
||||||
|
|
||||||
th := kusttest_test.MakeHarness(t)
|
|
||||||
for _, f := range input {
|
|
||||||
f(th)
|
|
||||||
}
|
|
||||||
openapi.ResetOpenAPI()
|
|
||||||
th.Run("prod", th.MakeDefaultOptions())
|
|
||||||
assert.Equal(t, "using custom schema from file provided", openapi.GetSchemaVersion())
|
|
||||||
}
|
|
||||||
|
|
||||||
// test for https://github.com/kubernetes-sigs/kustomize/issues/4179
|
|
||||||
// kustomize is not seeing the openapi field from the component defined in the overlay
|
|
||||||
func TestCustomOpenAPIFieldFromComponentWithOverlays(t *testing.T) {
|
|
||||||
if val, ok := os.LookupEnv("OPENAPI_TEST"); !ok || val != "true" {
|
|
||||||
t.SkipNow()
|
|
||||||
}
|
|
||||||
|
|
||||||
th := kusttest_test.MakeHarness(t)
|
|
||||||
|
|
||||||
// overlay declaring the component
|
|
||||||
th.WriteK("overlays/overlay-component-openapi", `resources:
|
|
||||||
- ../base/
|
|
||||||
components:
|
|
||||||
- ../../components/dc-openapi
|
|
||||||
`)
|
|
||||||
|
|
||||||
// base kustomization
|
|
||||||
th.WriteK("overlays/base", `resources:
|
|
||||||
- dc.yml
|
|
||||||
`)
|
|
||||||
|
|
||||||
// resource declared in the base kustomization
|
|
||||||
th.WriteF("overlays/base/dc.yml", `apiVersion: apps.openshift.io/v1
|
|
||||||
kind: DeploymentConfig
|
|
||||||
metadata:
|
|
||||||
name: my-dc
|
|
||||||
spec:
|
|
||||||
template:
|
|
||||||
spec:
|
|
||||||
initContainers:
|
|
||||||
- name: init
|
|
||||||
containers:
|
|
||||||
- name: container
|
|
||||||
env:
|
|
||||||
- name: foo
|
|
||||||
value: bar
|
|
||||||
volumeMounts:
|
|
||||||
- name: cm
|
|
||||||
mountPath: /opt/cm
|
|
||||||
volumes:
|
|
||||||
- name: cm
|
|
||||||
configMap:
|
|
||||||
name: cm
|
|
||||||
`)
|
|
||||||
|
|
||||||
// openapi schema referred to by the component
|
|
||||||
bytes, _ := ioutil.ReadFile("testdata/openshiftschema.json")
|
|
||||||
th.WriteF("components/dc-openapi/openapi.json", string(bytes))
|
|
||||||
|
|
||||||
// patch referred to by the component
|
|
||||||
th.WriteF("components/dc-openapi/patch.yml", `apiVersion: apps.openshift.io/v1
|
|
||||||
kind: DeploymentConfig
|
|
||||||
metadata:
|
|
||||||
name: my-dc
|
|
||||||
spec:
|
|
||||||
template:
|
|
||||||
spec:
|
|
||||||
containers:
|
|
||||||
- name: container
|
|
||||||
volumeMounts:
|
|
||||||
- name: additional-cm
|
|
||||||
mountPath: /mnt
|
|
||||||
volumes:
|
|
||||||
- name: additional-cm
|
|
||||||
configMap:
|
|
||||||
name: additional-cm
|
|
||||||
`)
|
|
||||||
|
|
||||||
// component declared in overlay with custom schema and patch
|
|
||||||
th.WriteC("components/dc-openapi", `patches:
|
|
||||||
- patch.yml
|
|
||||||
openapi:
|
|
||||||
path: openapi.json
|
|
||||||
`)
|
|
||||||
|
|
||||||
openapi.ResetOpenAPI()
|
|
||||||
m := th.Run("overlays/overlay-component-openapi", th.MakeDefaultOptions())
|
|
||||||
th.AssertActualEqualsExpected(m, `apiVersion: apps.openshift.io/v1
|
|
||||||
kind: DeploymentConfig
|
|
||||||
metadata:
|
|
||||||
name: my-dc
|
|
||||||
spec:
|
|
||||||
template:
|
|
||||||
spec:
|
|
||||||
containers:
|
|
||||||
- env:
|
|
||||||
- name: foo
|
|
||||||
value: bar
|
|
||||||
name: container
|
|
||||||
volumeMounts:
|
|
||||||
- mountPath: /mnt
|
|
||||||
name: additional-cm
|
|
||||||
- mountPath: /opt/cm
|
|
||||||
name: cm
|
|
||||||
initContainers:
|
|
||||||
- name: init
|
|
||||||
volumes:
|
|
||||||
- configMap:
|
|
||||||
name: additional-cm
|
|
||||||
name: additional-cm
|
|
||||||
- configMap:
|
|
||||||
name: cm
|
|
||||||
name: cm
|
|
||||||
`)
|
|
||||||
}
|
|
||||||
707
api/krusty/openapitests/openapicustomschema_test.go
Normal file
707
api/krusty/openapitests/openapicustomschema_test.go
Normal file
@@ -0,0 +1,707 @@
|
|||||||
|
// Copyright 2019 The Kubernetes Authors.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
// The openapi field tests are separated due to the global OpenAPI variable causing
|
||||||
|
// race conditions. As a result, these tests can't be run in parallel with the other tests.
|
||||||
|
package openapitests //nolint
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
|
||||||
|
"sigs.k8s.io/kustomize/kyaml/openapi"
|
||||||
|
"sigs.k8s.io/kustomize/kyaml/openapi/kubernetesapi"
|
||||||
|
)
|
||||||
|
|
||||||
|
func writeTestSchema(th kusttest_test.Harness, filepath string) {
|
||||||
|
bytes, _ := ioutil.ReadFile("../testdata/customschema.json")
|
||||||
|
th.WriteF(filepath+"mycrd_schema.json", string(bytes))
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeTestSchemaYaml(th kusttest_test.Harness, filepath string) {
|
||||||
|
bytes, _ := ioutil.ReadFile("../testdata/customschema.yaml")
|
||||||
|
th.WriteF(filepath+"mycrd_schema.yaml", string(bytes))
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeCustomResource(th kusttest_test.Harness, filepath string) {
|
||||||
|
th.WriteF(filepath, `
|
||||||
|
apiVersion: example.com/v1alpha1
|
||||||
|
kind: MyCRD
|
||||||
|
metadata:
|
||||||
|
name: service
|
||||||
|
spec:
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: server
|
||||||
|
image: server
|
||||||
|
command: example
|
||||||
|
ports:
|
||||||
|
- name: grpc
|
||||||
|
protocol: TCP
|
||||||
|
containerPort: 8080
|
||||||
|
`)
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeOtherCustomResource(th kusttest_test.Harness, filepath string) {
|
||||||
|
th.WriteF(filepath, `
|
||||||
|
apiVersion: v1alpha1
|
||||||
|
kind: MyCRD
|
||||||
|
metadata:
|
||||||
|
name: service
|
||||||
|
spec:
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: server
|
||||||
|
image: server
|
||||||
|
command: example
|
||||||
|
ports:
|
||||||
|
- name: grpc
|
||||||
|
protocol: TCP
|
||||||
|
containerPort: 8080
|
||||||
|
`)
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeTestComponentWithCustomSchema(th kusttest_test.Harness) {
|
||||||
|
writeTestSchema(th, "comp/")
|
||||||
|
openapi.ResetOpenAPI()
|
||||||
|
th.WriteC("comp", `
|
||||||
|
openapi:
|
||||||
|
path: mycrd_schema.json
|
||||||
|
`)
|
||||||
|
th.WriteF("comp/stub.yaml", `
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: stub
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const customSchemaPatch = `
|
||||||
|
patchesStrategicMerge:
|
||||||
|
- |-
|
||||||
|
apiVersion: example.com/v1alpha1
|
||||||
|
kind: MyCRD
|
||||||
|
metadata:
|
||||||
|
name: service
|
||||||
|
spec:
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: server
|
||||||
|
image: nginx
|
||||||
|
`
|
||||||
|
|
||||||
|
const customSchemaPatchMultipleGvks = `
|
||||||
|
patchesStrategicMerge:
|
||||||
|
- |-
|
||||||
|
apiVersion: example.com/v1alpha1
|
||||||
|
kind: MyCRD
|
||||||
|
metadata:
|
||||||
|
name: service
|
||||||
|
spec:
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: server
|
||||||
|
image: nginx
|
||||||
|
- |-
|
||||||
|
apiVersion: v1alpha1
|
||||||
|
kind: MyCRD
|
||||||
|
metadata:
|
||||||
|
name: service
|
||||||
|
spec:
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: server
|
||||||
|
image: nginx
|
||||||
|
`
|
||||||
|
|
||||||
|
const patchedCustomResource = `
|
||||||
|
apiVersion: example.com/v1alpha1
|
||||||
|
kind: MyCRD
|
||||||
|
metadata:
|
||||||
|
name: service
|
||||||
|
spec:
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- command: example
|
||||||
|
image: nginx
|
||||||
|
name: server
|
||||||
|
ports:
|
||||||
|
- containerPort: 8080
|
||||||
|
name: grpc
|
||||||
|
protocol: TCP
|
||||||
|
`
|
||||||
|
|
||||||
|
func runOpenApiTest(t *testing.T, test func(t *testing.T)) {
|
||||||
|
t.Helper()
|
||||||
|
if val, ok := os.LookupEnv("OPENAPI_TEST"); !ok || val != "true" {
|
||||||
|
t.SkipNow()
|
||||||
|
}
|
||||||
|
test(t)
|
||||||
|
openapi.ResetOpenAPI()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test for issue #2825
|
||||||
|
func TestCustomOpenApiFieldBasicUsage(t *testing.T) {
|
||||||
|
runOpenApiTest(t, func(t *testing.T) {
|
||||||
|
t.Helper()
|
||||||
|
th := kusttest_test.MakeHarness(t)
|
||||||
|
th.WriteK(".", `
|
||||||
|
resources:
|
||||||
|
- mycrd.yaml
|
||||||
|
openapi:
|
||||||
|
path: mycrd_schema.json
|
||||||
|
`+customSchemaPatch)
|
||||||
|
writeCustomResource(th, "mycrd.yaml")
|
||||||
|
writeTestSchema(th, "./")
|
||||||
|
m := th.Run(".", th.MakeDefaultOptions())
|
||||||
|
th.AssertActualEqualsExpected(m, patchedCustomResource)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCustomOpenApiFieldBasicUsageWithRemoteSchema(t *testing.T) {
|
||||||
|
runOpenApiTest(t, func(t *testing.T) {
|
||||||
|
t.Helper()
|
||||||
|
th := kusttest_test.MakeHarness(t)
|
||||||
|
th.WriteK(".", `
|
||||||
|
resources:
|
||||||
|
- mycrd.yaml
|
||||||
|
openapi:
|
||||||
|
path: https://github.com/kubernetes-sigs/kustomize/raw/master/api/krusty/testdata/customschema.json
|
||||||
|
`+customSchemaPatch)
|
||||||
|
writeCustomResource(th, "mycrd.yaml")
|
||||||
|
writeTestSchema(th, "./")
|
||||||
|
m := th.Run(".", th.MakeDefaultOptions())
|
||||||
|
th.AssertActualEqualsExpected(m, patchedCustomResource)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCustomOpenApiFieldWithTwoGvks(t *testing.T) {
|
||||||
|
runOpenApiTest(t, func(t *testing.T) {
|
||||||
|
t.Helper()
|
||||||
|
th := kusttest_test.MakeHarness(t)
|
||||||
|
th.WriteK(".", `
|
||||||
|
resources:
|
||||||
|
- mycrd.yaml
|
||||||
|
- myothercrd.yaml
|
||||||
|
openapi:
|
||||||
|
path: mycrd_schema.json
|
||||||
|
`+customSchemaPatchMultipleGvks)
|
||||||
|
writeCustomResource(th, "mycrd.yaml")
|
||||||
|
writeOtherCustomResource(th, "myothercrd.yaml")
|
||||||
|
writeTestSchema(th, "./")
|
||||||
|
m := th.Run(".", th.MakeDefaultOptions())
|
||||||
|
th.AssertActualEqualsExpected(m, `apiVersion: example.com/v1alpha1
|
||||||
|
kind: MyCRD
|
||||||
|
metadata:
|
||||||
|
name: service
|
||||||
|
spec:
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- command: example
|
||||||
|
image: nginx
|
||||||
|
name: server
|
||||||
|
ports:
|
||||||
|
- containerPort: 8080
|
||||||
|
name: grpc
|
||||||
|
protocol: TCP
|
||||||
|
---
|
||||||
|
apiVersion: v1alpha1
|
||||||
|
kind: MyCRD
|
||||||
|
metadata:
|
||||||
|
name: service
|
||||||
|
spec:
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- command: example
|
||||||
|
image: nginx
|
||||||
|
name: server
|
||||||
|
ports:
|
||||||
|
- containerPort: 8080
|
||||||
|
name: grpc
|
||||||
|
protocol: TCP
|
||||||
|
`)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCustomOpenApiFieldYaml(t *testing.T) {
|
||||||
|
runOpenApiTest(t, func(t *testing.T) {
|
||||||
|
t.Helper()
|
||||||
|
th := kusttest_test.MakeHarness(t)
|
||||||
|
th.WriteK(".", `
|
||||||
|
resources:
|
||||||
|
- mycrd.yaml
|
||||||
|
openapi:
|
||||||
|
path: mycrd_schema.yaml
|
||||||
|
`+customSchemaPatch)
|
||||||
|
writeCustomResource(th, "mycrd.yaml")
|
||||||
|
writeTestSchemaYaml(th, "./")
|
||||||
|
m := th.Run(".", th.MakeDefaultOptions())
|
||||||
|
th.AssertActualEqualsExpected(m, patchedCustomResource)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error if user tries to specify both builtin version
|
||||||
|
// and custom schema
|
||||||
|
func TestCustomOpenApiFieldBothPathAndVersion(t *testing.T) {
|
||||||
|
runOpenApiTest(t, func(t *testing.T) {
|
||||||
|
t.Helper()
|
||||||
|
th := kusttest_test.MakeHarness(t)
|
||||||
|
th.WriteK(".", `
|
||||||
|
resources:
|
||||||
|
- mycrd.yaml
|
||||||
|
openapi:
|
||||||
|
version: v1.21.2
|
||||||
|
path: mycrd_schema.json
|
||||||
|
`+customSchemaPatch)
|
||||||
|
writeCustomResource(th, "mycrd.yaml")
|
||||||
|
writeTestSchema(th, "./")
|
||||||
|
err := th.RunWithErr(".", th.MakeDefaultOptions())
|
||||||
|
assert.Error(t, err)
|
||||||
|
assert.Equal(t,
|
||||||
|
"builtin version and custom schema provided, cannot use both",
|
||||||
|
err.Error())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test for if the filepath specified is not found
|
||||||
|
func TestCustomOpenApiFieldFileNotFound(t *testing.T) {
|
||||||
|
runOpenApiTest(t, func(t *testing.T) {
|
||||||
|
t.Helper()
|
||||||
|
th := kusttest_test.MakeHarness(t)
|
||||||
|
th.WriteK(".", `
|
||||||
|
resources:
|
||||||
|
- mycrd.yaml
|
||||||
|
openapi:
|
||||||
|
path: mycrd_schema.json
|
||||||
|
`+customSchemaPatch)
|
||||||
|
writeCustomResource(th, "mycrd.yaml")
|
||||||
|
err := th.RunWithErr(".", th.MakeDefaultOptions())
|
||||||
|
assert.Error(t, err)
|
||||||
|
assert.Equal(t,
|
||||||
|
"'/mycrd_schema.json' doesn't exist",
|
||||||
|
err.Error())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCustomOpenApiFieldFromBase(t *testing.T) {
|
||||||
|
runOpenApiTest(t, func(t *testing.T) {
|
||||||
|
t.Helper()
|
||||||
|
th := kusttest_test.MakeHarness(t)
|
||||||
|
th.WriteK("base", `
|
||||||
|
resources:
|
||||||
|
- mycrd.yaml
|
||||||
|
openapi:
|
||||||
|
path: mycrd_schema.json
|
||||||
|
`)
|
||||||
|
th.WriteK("overlay", `
|
||||||
|
resources:
|
||||||
|
- ../base
|
||||||
|
`+customSchemaPatch)
|
||||||
|
writeCustomResource(th, "base/mycrd.yaml")
|
||||||
|
writeTestSchema(th, "base/")
|
||||||
|
m := th.Run("overlay", th.MakeDefaultOptions())
|
||||||
|
th.AssertActualEqualsExpected(m, patchedCustomResource)
|
||||||
|
assert.Equal(t, "using custom schema from file provided",
|
||||||
|
openapi.GetSchemaVersion())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCustomOpenApiFieldFromBaseWithRemoteSchema(t *testing.T) {
|
||||||
|
runOpenApiTest(t, func(t *testing.T) {
|
||||||
|
t.Helper()
|
||||||
|
th := kusttest_test.MakeHarness(t)
|
||||||
|
th.WriteK("base", `
|
||||||
|
resources:
|
||||||
|
- mycrd.yaml
|
||||||
|
openapi:
|
||||||
|
path: https://github.com/kubernetes-sigs/kustomize/raw/master/api/krusty/testdata/customschema.json
|
||||||
|
`)
|
||||||
|
th.WriteK("overlay", `
|
||||||
|
resources:
|
||||||
|
- ../base
|
||||||
|
`+customSchemaPatch)
|
||||||
|
writeCustomResource(th, "base/mycrd.yaml")
|
||||||
|
writeTestSchema(th, "base/")
|
||||||
|
m := th.Run("overlay", th.MakeDefaultOptions())
|
||||||
|
th.AssertActualEqualsExpected(m, patchedCustomResource)
|
||||||
|
assert.Equal(t, "using custom schema from file provided",
|
||||||
|
openapi.GetSchemaVersion())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCustomOpenApiFieldFromOverlay(t *testing.T) {
|
||||||
|
runOpenApiTest(t, func(t *testing.T) {
|
||||||
|
t.Helper()
|
||||||
|
th := kusttest_test.MakeHarness(t)
|
||||||
|
th.WriteK("base", `
|
||||||
|
resources:
|
||||||
|
- mycrd.yaml
|
||||||
|
`)
|
||||||
|
th.WriteK("overlay", `
|
||||||
|
resources:
|
||||||
|
- ../base
|
||||||
|
openapi:
|
||||||
|
path: mycrd_schema.json
|
||||||
|
`+customSchemaPatch)
|
||||||
|
writeCustomResource(th, "base/mycrd.yaml")
|
||||||
|
writeTestSchema(th, "overlay/")
|
||||||
|
m := th.Run("overlay", th.MakeDefaultOptions())
|
||||||
|
th.AssertActualEqualsExpected(m, patchedCustomResource)
|
||||||
|
assert.Equal(t, "using custom schema from file provided",
|
||||||
|
openapi.GetSchemaVersion())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCustomOpenApiFieldFromOverlayWithRemoteSchema(t *testing.T) {
|
||||||
|
runOpenApiTest(t, func(t *testing.T) {
|
||||||
|
t.Helper()
|
||||||
|
th := kusttest_test.MakeHarness(t)
|
||||||
|
th.WriteK("base", `
|
||||||
|
resources:
|
||||||
|
- mycrd.yaml
|
||||||
|
`)
|
||||||
|
th.WriteK("overlay", `
|
||||||
|
resources:
|
||||||
|
- ../base
|
||||||
|
openapi:
|
||||||
|
path: https://github.com/kubernetes-sigs/kustomize/raw/master/api/krusty/testdata/customschema.json
|
||||||
|
`+customSchemaPatch)
|
||||||
|
writeCustomResource(th, "base/mycrd.yaml")
|
||||||
|
writeTestSchema(th, "overlay/")
|
||||||
|
m := th.Run("overlay", th.MakeDefaultOptions())
|
||||||
|
th.AssertActualEqualsExpected(m, patchedCustomResource)
|
||||||
|
assert.Equal(t, "using custom schema from file provided",
|
||||||
|
openapi.GetSchemaVersion())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCustomOpenApiFieldOverlayTakesPrecedence(t *testing.T) {
|
||||||
|
runOpenApiTest(t, func(t *testing.T) {
|
||||||
|
t.Helper()
|
||||||
|
th := kusttest_test.MakeHarness(t)
|
||||||
|
openapi.ResetOpenAPI()
|
||||||
|
th.WriteK("base", `
|
||||||
|
resources:
|
||||||
|
- mycrd.yaml
|
||||||
|
openapi:
|
||||||
|
path: mycrd_schema.json
|
||||||
|
`)
|
||||||
|
th.WriteK("overlay", `
|
||||||
|
resources:
|
||||||
|
- ../base
|
||||||
|
openapi:
|
||||||
|
version: v1.21.2
|
||||||
|
`+customSchemaPatch)
|
||||||
|
writeCustomResource(th, "base/mycrd.yaml")
|
||||||
|
writeTestSchema(th, "base/")
|
||||||
|
m := th.Run("overlay", th.MakeDefaultOptions())
|
||||||
|
th.AssertActualEqualsExpected(m, `
|
||||||
|
apiVersion: example.com/v1alpha1
|
||||||
|
kind: MyCRD
|
||||||
|
metadata:
|
||||||
|
name: service
|
||||||
|
spec:
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- image: nginx
|
||||||
|
name: server
|
||||||
|
`)
|
||||||
|
assert.Equal(t, "v1212", openapi.GetSchemaVersion())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCustomOpenApiFieldFromComponent(t *testing.T) {
|
||||||
|
runOpenApiTest(t, func(t *testing.T) {
|
||||||
|
t.Helper()
|
||||||
|
input := []FileGen{
|
||||||
|
writeTestBase,
|
||||||
|
writeTestComponentWithCustomSchema,
|
||||||
|
writeOverlayProd}
|
||||||
|
|
||||||
|
th := kusttest_test.MakeHarness(t)
|
||||||
|
for _, f := range input {
|
||||||
|
f(th)
|
||||||
|
}
|
||||||
|
th.Run("prod", th.MakeDefaultOptions())
|
||||||
|
assert.Equal(t, "using custom schema from file provided", openapi.GetSchemaVersion())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// test for https://github.com/kubernetes-sigs/kustomize/issues/4179
|
||||||
|
// kustomize is not seeing the openapi field from the component defined in the overlay
|
||||||
|
func TestCustomOpenApiFieldFromComponentWithOverlays(t *testing.T) {
|
||||||
|
runOpenApiTest(t, func(t *testing.T) {
|
||||||
|
t.Helper()
|
||||||
|
th := kusttest_test.MakeHarness(t)
|
||||||
|
|
||||||
|
// overlay declaring the component
|
||||||
|
th.WriteK("overlays/overlay-component-openapi", `resources:
|
||||||
|
- ../base/
|
||||||
|
components:
|
||||||
|
- ../../components/dc-openapi
|
||||||
|
`)
|
||||||
|
|
||||||
|
// base kustomization
|
||||||
|
th.WriteK("overlays/base", `resources:
|
||||||
|
- dc.yml
|
||||||
|
`)
|
||||||
|
|
||||||
|
// resource declared in the base kustomization
|
||||||
|
th.WriteF("overlays/base/dc.yml", `apiVersion: apps.openshift.io/v1
|
||||||
|
kind: DeploymentConfig
|
||||||
|
metadata:
|
||||||
|
name: my-dc
|
||||||
|
spec:
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
initContainers:
|
||||||
|
- name: init
|
||||||
|
containers:
|
||||||
|
- name: container
|
||||||
|
env:
|
||||||
|
- name: foo
|
||||||
|
value: bar
|
||||||
|
volumeMounts:
|
||||||
|
- name: cm
|
||||||
|
mountPath: /opt/cm
|
||||||
|
volumes:
|
||||||
|
- name: cm
|
||||||
|
configMap:
|
||||||
|
name: cm
|
||||||
|
`)
|
||||||
|
|
||||||
|
// openapi schema referred to by the component
|
||||||
|
bytes, _ := ioutil.ReadFile("../testdata/openshiftschema.json")
|
||||||
|
th.WriteF("components/dc-openapi/openapi.json", string(bytes))
|
||||||
|
|
||||||
|
// patch referred to by the component
|
||||||
|
th.WriteF("components/dc-openapi/patch.yml", `apiVersion: apps.openshift.io/v1
|
||||||
|
kind: DeploymentConfig
|
||||||
|
metadata:
|
||||||
|
name: my-dc
|
||||||
|
spec:
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: container
|
||||||
|
volumeMounts:
|
||||||
|
- name: additional-cm
|
||||||
|
mountPath: /mnt
|
||||||
|
volumes:
|
||||||
|
- name: additional-cm
|
||||||
|
configMap:
|
||||||
|
name: additional-cm
|
||||||
|
`)
|
||||||
|
|
||||||
|
// component declared in overlay with custom schema and patch
|
||||||
|
th.WriteC("components/dc-openapi", `patches:
|
||||||
|
- patch.yml
|
||||||
|
openapi:
|
||||||
|
path: openapi.json
|
||||||
|
`)
|
||||||
|
|
||||||
|
m := th.Run("overlays/overlay-component-openapi", th.MakeDefaultOptions())
|
||||||
|
th.AssertActualEqualsExpected(m, `apiVersion: apps.openshift.io/v1
|
||||||
|
kind: DeploymentConfig
|
||||||
|
metadata:
|
||||||
|
name: my-dc
|
||||||
|
spec:
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- env:
|
||||||
|
- name: foo
|
||||||
|
value: bar
|
||||||
|
name: container
|
||||||
|
volumeMounts:
|
||||||
|
- mountPath: /mnt
|
||||||
|
name: additional-cm
|
||||||
|
- mountPath: /opt/cm
|
||||||
|
name: cm
|
||||||
|
initContainers:
|
||||||
|
- name: init
|
||||||
|
volumes:
|
||||||
|
- configMap:
|
||||||
|
name: additional-cm
|
||||||
|
name: additional-cm
|
||||||
|
- configMap:
|
||||||
|
name: cm
|
||||||
|
name: cm
|
||||||
|
`)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCustomOpenApiFieldVersion(t *testing.T) {
|
||||||
|
runOpenApiTest(t, func(t *testing.T) {
|
||||||
|
t.Helper()
|
||||||
|
th := kusttest_test.MakeHarness(t)
|
||||||
|
th.WriteK(".", `
|
||||||
|
openapi:
|
||||||
|
version: v1.21.2
|
||||||
|
resources:
|
||||||
|
- deployment.yaml
|
||||||
|
`)
|
||||||
|
th.WriteF("deployment.yaml", `
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: myDeployment
|
||||||
|
spec:
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- image: whatever
|
||||||
|
`)
|
||||||
|
|
||||||
|
m := th.Run(".", th.MakeDefaultOptions())
|
||||||
|
th.AssertActualEqualsExpected(m, `
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: myDeployment
|
||||||
|
spec:
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- image: whatever
|
||||||
|
`)
|
||||||
|
assert.Equal(t, "v1212", openapi.GetSchemaVersion())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCustomOpenApiFieldNotBuiltin(t *testing.T) {
|
||||||
|
runOpenApiTest(t, func(t *testing.T) {
|
||||||
|
t.Helper()
|
||||||
|
th := kusttest_test.MakeHarness(t)
|
||||||
|
th.WriteK(".", `
|
||||||
|
openapi:
|
||||||
|
version: v1.14.1
|
||||||
|
resources:
|
||||||
|
- deployment.yaml
|
||||||
|
`)
|
||||||
|
th.WriteF("deployment.yaml", `
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: myDeployment
|
||||||
|
spec:
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- image: whatever
|
||||||
|
`)
|
||||||
|
|
||||||
|
err := th.RunWithErr(".", th.MakeDefaultOptions())
|
||||||
|
if err == nil {
|
||||||
|
t.Fatalf("expected an error")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCustomOpenApiFieldDefaultVersion(t *testing.T) {
|
||||||
|
runOpenApiTest(t, func(t *testing.T) {
|
||||||
|
t.Helper()
|
||||||
|
th := kusttest_test.MakeHarness(t)
|
||||||
|
th.WriteK(".", `
|
||||||
|
resources:
|
||||||
|
- deployment.yaml
|
||||||
|
`)
|
||||||
|
th.WriteF("deployment.yaml", `
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: myDeployment
|
||||||
|
spec:
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- image: whatever
|
||||||
|
`)
|
||||||
|
|
||||||
|
m := th.Run(".", th.MakeDefaultOptions())
|
||||||
|
th.AssertActualEqualsExpected(m, `
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: myDeployment
|
||||||
|
spec:
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- image: whatever
|
||||||
|
`)
|
||||||
|
assert.Equal(t, kubernetesapi.DefaultOpenAPI, openapi.GetSchemaVersion())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// The following definitions are copied from the krusty package.
|
||||||
|
|
||||||
|
type FileGen func(kusttest_test.Harness)
|
||||||
|
|
||||||
|
func writeTestBase(th kusttest_test.Harness) {
|
||||||
|
th.WriteK("base", `
|
||||||
|
resources:
|
||||||
|
- deploy.yaml
|
||||||
|
configMapGenerator:
|
||||||
|
- name: my-configmap
|
||||||
|
literals:
|
||||||
|
- testValue=purple
|
||||||
|
- otherValue=green
|
||||||
|
`)
|
||||||
|
th.WriteF("base/deploy.yaml", `
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: storefront
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
`)
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeOverlayProd(th kusttest_test.Harness) {
|
||||||
|
th.WriteK("prod", `
|
||||||
|
resources:
|
||||||
|
- ../base
|
||||||
|
- db
|
||||||
|
|
||||||
|
components:
|
||||||
|
- ../comp
|
||||||
|
`)
|
||||||
|
writeDB(th)
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeDB(th kusttest_test.Harness) {
|
||||||
|
deployment("db", "prod/db")(th)
|
||||||
|
}
|
||||||
|
|
||||||
|
func deployment(name string, path string) FileGen {
|
||||||
|
return writeF(path, fmt.Sprintf(`
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: %s
|
||||||
|
spec:
|
||||||
|
type: Logical
|
||||||
|
`, name))
|
||||||
|
}
|
||||||
|
|
||||||
|
func writeF(path string, content string) FileGen {
|
||||||
|
return func(th kusttest_test.Harness) {
|
||||||
|
th.WriteF(path, content)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,110 +0,0 @@
|
|||||||
// Copyright 2019 The Kubernetes Authors.
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
package krusty_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
|
|
||||||
"sigs.k8s.io/kustomize/kyaml/openapi"
|
|
||||||
"sigs.k8s.io/kustomize/kyaml/openapi/kubernetesapi"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestOpenApiFieldBasicUsage(t *testing.T) {
|
|
||||||
th := kusttest_test.MakeHarness(t)
|
|
||||||
th.WriteK(".", `
|
|
||||||
openapi:
|
|
||||||
version: v1.21.2
|
|
||||||
resources:
|
|
||||||
- deployment.yaml
|
|
||||||
`)
|
|
||||||
th.WriteF("deployment.yaml", `
|
|
||||||
apiVersion: apps/v1
|
|
||||||
kind: Deployment
|
|
||||||
metadata:
|
|
||||||
name: myDeployment
|
|
||||||
spec:
|
|
||||||
template:
|
|
||||||
spec:
|
|
||||||
containers:
|
|
||||||
- image: whatever
|
|
||||||
`)
|
|
||||||
|
|
||||||
m := th.Run(".", th.MakeDefaultOptions())
|
|
||||||
th.AssertActualEqualsExpected(m, `
|
|
||||||
apiVersion: apps/v1
|
|
||||||
kind: Deployment
|
|
||||||
metadata:
|
|
||||||
name: myDeployment
|
|
||||||
spec:
|
|
||||||
template:
|
|
||||||
spec:
|
|
||||||
containers:
|
|
||||||
- image: whatever
|
|
||||||
`)
|
|
||||||
assert.Equal(t, "v1212", openapi.GetSchemaVersion())
|
|
||||||
openapi.ResetOpenAPI()
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestOpenApiFieldNotBuiltin(t *testing.T) {
|
|
||||||
th := kusttest_test.MakeHarness(t)
|
|
||||||
th.WriteK(".", `
|
|
||||||
openapi:
|
|
||||||
version: v1.14.1
|
|
||||||
resources:
|
|
||||||
- deployment.yaml
|
|
||||||
`)
|
|
||||||
th.WriteF("deployment.yaml", `
|
|
||||||
apiVersion: apps/v1
|
|
||||||
kind: Deployment
|
|
||||||
metadata:
|
|
||||||
name: myDeployment
|
|
||||||
spec:
|
|
||||||
template:
|
|
||||||
spec:
|
|
||||||
containers:
|
|
||||||
- image: whatever
|
|
||||||
`)
|
|
||||||
|
|
||||||
err := th.RunWithErr(".", th.MakeDefaultOptions())
|
|
||||||
if err == nil {
|
|
||||||
t.Fatalf("expected an error")
|
|
||||||
}
|
|
||||||
openapi.ResetOpenAPI()
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestOpenApiFieldDefaultVersion(t *testing.T) {
|
|
||||||
th := kusttest_test.MakeHarness(t)
|
|
||||||
th.WriteK(".", `
|
|
||||||
resources:
|
|
||||||
- deployment.yaml
|
|
||||||
`)
|
|
||||||
th.WriteF("deployment.yaml", `
|
|
||||||
apiVersion: apps/v1
|
|
||||||
kind: Deployment
|
|
||||||
metadata:
|
|
||||||
name: myDeployment
|
|
||||||
spec:
|
|
||||||
template:
|
|
||||||
spec:
|
|
||||||
containers:
|
|
||||||
- image: whatever
|
|
||||||
`)
|
|
||||||
|
|
||||||
m := th.Run(".", th.MakeDefaultOptions())
|
|
||||||
th.AssertActualEqualsExpected(m, `
|
|
||||||
apiVersion: apps/v1
|
|
||||||
kind: Deployment
|
|
||||||
metadata:
|
|
||||||
name: myDeployment
|
|
||||||
spec:
|
|
||||||
template:
|
|
||||||
spec:
|
|
||||||
containers:
|
|
||||||
- image: whatever
|
|
||||||
`)
|
|
||||||
assert.Equal(t, kubernetesapi.DefaultOpenAPI, openapi.GetSchemaVersion())
|
|
||||||
openapi.ResetOpenAPI()
|
|
||||||
}
|
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// Copyright 2022 The Kubernetes Authors.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
package krusty_test
|
package krusty_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
package krusty_test
|
package krusty_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
@@ -27,8 +26,13 @@ func TestPluginEnvironment(t *testing.T) {
|
|||||||
kusttest_test.MakeHarnessWithFs(t, filesys.MakeFsInMemory()),
|
kusttest_test.MakeHarnessWithFs(t, filesys.MakeFsInMemory()),
|
||||||
filesys.Separator)
|
filesys.Separator)
|
||||||
|
|
||||||
dir := makeTmpDir(t)
|
// On MacOS, $TMPDIR is by default set to /var/folders/…, with /var a
|
||||||
defer os.RemoveAll(dir)
|
// symlink to /private/var , which does not match our expectations
|
||||||
|
dir, err := filepath.EvalSymlinks(t.TempDir())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("err: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
confirmBehavior(
|
confirmBehavior(
|
||||||
kusttest_test.MakeHarnessWithFs(t, filesys.MakeFsOnDisk()),
|
kusttest_test.MakeHarnessWithFs(t, filesys.MakeFsOnDisk()),
|
||||||
dir)
|
dir)
|
||||||
@@ -65,15 +69,3 @@ metadata:
|
|||||||
name: hello
|
name: hello
|
||||||
`)
|
`)
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeTmpDir(t *testing.T) string {
|
|
||||||
base, err := os.Getwd()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("err %v", err)
|
|
||||||
}
|
|
||||||
dir, err := ioutil.TempDir(base, "kustomize-tmp-test-")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("err %v", err)
|
|
||||||
}
|
|
||||||
return dir
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -9,29 +9,20 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/require"
|
||||||
"sigs.k8s.io/kustomize/api/internal/utils"
|
|
||||||
"sigs.k8s.io/kustomize/api/krusty"
|
"sigs.k8s.io/kustomize/api/krusty"
|
||||||
"sigs.k8s.io/kustomize/api/loader"
|
"sigs.k8s.io/kustomize/api/loader"
|
||||||
|
"sigs.k8s.io/kustomize/api/resmap"
|
||||||
"sigs.k8s.io/kustomize/kyaml/filesys"
|
"sigs.k8s.io/kustomize/kyaml/filesys"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestRemoteLoad(t *testing.T) {
|
const resourcesField = `resources:
|
||||||
fSys := filesys.MakeFsOnDisk()
|
- %s`
|
||||||
b := krusty.MakeKustomizer(krusty.MakeDefaultOptions())
|
const resourceErrorFormat = "accumulating resources: accumulation err='accumulating resources from '%s': "
|
||||||
m, err := b.Run(
|
const fileError = "evalsymlink failure"
|
||||||
fSys,
|
const repoFindError = "URL is a git repository"
|
||||||
"github.com/kubernetes-sigs/kustomize/examples/multibases/dev/?ref=v1.0.6")
|
|
||||||
if utils.IsErrTimeout(err) {
|
const multibaseDevExampleBuild = `apiVersion: v1
|
||||||
// Don't fail on timeouts.
|
|
||||||
t.SkipNow()
|
|
||||||
}
|
|
||||||
if !assert.NoError(t, err) {
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
yml, err := m.AsYaml()
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.Equal(t, `apiVersion: v1
|
|
||||||
kind: Pod
|
kind: Pod
|
||||||
metadata:
|
metadata:
|
||||||
labels:
|
labels:
|
||||||
@@ -41,88 +32,332 @@ spec:
|
|||||||
containers:
|
containers:
|
||||||
- image: nginx:1.7.9
|
- image: nginx:1.7.9
|
||||||
name: nginx
|
name: nginx
|
||||||
`, string(yml))
|
`
|
||||||
|
|
||||||
|
type remoteResourceCase struct {
|
||||||
|
skip bool
|
||||||
|
kustomization string
|
||||||
|
error bool
|
||||||
|
expected string // if error, expected is error string
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRemoteResource(t *testing.T) {
|
func createKustDir(content string, require *require.Assertions) (filesys.FileSystem, filesys.ConfirmedDir) {
|
||||||
fSys := filesys.MakeFsOnDisk()
|
fSys := filesys.MakeFsOnDisk()
|
||||||
b := krusty.MakeKustomizer(krusty.MakeDefaultOptions())
|
|
||||||
tmpDir, err := filesys.NewTmpConfirmedDir()
|
tmpDir, err := filesys.NewTmpConfirmedDir()
|
||||||
assert.NoError(t, err)
|
require.NoError(err)
|
||||||
assert.NoError(t, fSys.WriteFile(filepath.Join(tmpDir.String(), "kustomization.yaml"), []byte(`
|
require.NoError(fSys.WriteFile(filepath.Join(tmpDir.String(), "kustomization.yaml"), []byte(content)))
|
||||||
resources:
|
return fSys, tmpDir
|
||||||
- github.com/kubernetes-sigs/kustomize/examples/multibases/dev/?ref=v1.0.6
|
}
|
||||||
`)))
|
|
||||||
|
func checkYaml(actual resmap.ResMap, expected string, require *require.Assertions) {
|
||||||
|
yml, err := actual.AsYaml()
|
||||||
|
require.NoError(err)
|
||||||
|
require.Equal(expected, string(yml))
|
||||||
|
}
|
||||||
|
|
||||||
|
func testRemoteResource(require *require.Assertions, test *remoteResourceCase) {
|
||||||
|
fSys, tmpDir := createKustDir(test.kustomization, require)
|
||||||
|
|
||||||
|
b := krusty.MakeKustomizer(krusty.MakeDefaultOptions())
|
||||||
m, err := b.Run(
|
m, err := b.Run(
|
||||||
fSys,
|
fSys,
|
||||||
tmpDir.String())
|
tmpDir.String())
|
||||||
if utils.IsErrTimeout(err) {
|
|
||||||
// Don't fail on timeouts.
|
if test.error {
|
||||||
t.SkipNow()
|
require.Error(err)
|
||||||
|
require.Contains(err.Error(), test.expected)
|
||||||
|
} else {
|
||||||
|
require.NoError(err)
|
||||||
|
checkYaml(m, test.expected, require)
|
||||||
}
|
}
|
||||||
assert.NoError(t, err)
|
|
||||||
yml, err := m.AsYaml()
|
require.NoError(fSys.RemoveAll(tmpDir.String()))
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.Equal(t, `apiVersion: v1
|
|
||||||
kind: Pod
|
|
||||||
metadata:
|
|
||||||
labels:
|
|
||||||
app: myapp
|
|
||||||
name: dev-myapp-pod
|
|
||||||
spec:
|
|
||||||
containers:
|
|
||||||
- image: nginx:1.7.9
|
|
||||||
name: nginx
|
|
||||||
`, string(yml))
|
|
||||||
assert.NoError(t, fSys.RemoveAll(tmpDir.String()))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRemoteResourceWithHTTPError(t *testing.T) {
|
func TestRemoteLoad(t *testing.T) {
|
||||||
|
require := require.New(t)
|
||||||
|
|
||||||
fSys := filesys.MakeFsOnDisk()
|
fSys := filesys.MakeFsOnDisk()
|
||||||
b := krusty.MakeKustomizer(krusty.MakeDefaultOptions())
|
b := krusty.MakeKustomizer(krusty.MakeDefaultOptions())
|
||||||
tmpDir, err := filesys.NewTmpConfirmedDir()
|
|
||||||
assert.NoError(t, err)
|
m, err := b.Run(
|
||||||
|
fSys,
|
||||||
|
"github.com/kubernetes-sigs/kustomize/examples/multibases/dev/?ref=v1.0.6")
|
||||||
|
require.NoError(err)
|
||||||
|
checkYaml(m, multibaseDevExampleBuild, require)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRemoteResourceHttps(t *testing.T) {
|
||||||
|
tests := map[string]remoteResourceCase{
|
||||||
|
"basic": {
|
||||||
|
kustomization: `
|
||||||
|
resources:
|
||||||
|
- https://github.com/kubernetes-sigs/kustomize//examples/multibases/dev/?ref=v1.0.6`,
|
||||||
|
expected: multibaseDevExampleBuild,
|
||||||
|
},
|
||||||
|
".git repo suffix, no slash suffix": {
|
||||||
|
kustomization: `
|
||||||
|
resources:
|
||||||
|
- https://github.com/kubernetes-sigs/kustomize.git//examples/multibases/dev?ref=v1.0.6`,
|
||||||
|
expected: multibaseDevExampleBuild,
|
||||||
|
},
|
||||||
|
"repo": {
|
||||||
|
kustomization: `
|
||||||
|
resources:
|
||||||
|
- https://github.com/annasong20/kustomize-test.git?ref=main`,
|
||||||
|
expected: multibaseDevExampleBuild,
|
||||||
|
},
|
||||||
|
"raw remote file": {
|
||||||
|
kustomization: `
|
||||||
|
resources:
|
||||||
|
- https://raw.githubusercontent.com/kubernetes-sigs/kustomize/v3.1.0/examples/multibases/base/pod.yaml
|
||||||
|
namePrefix: dev-`,
|
||||||
|
expected: multibaseDevExampleBuild,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for name, test := range tests {
|
||||||
|
test := test
|
||||||
|
t.Run(name, func(t *testing.T) {
|
||||||
|
if test.skip {
|
||||||
|
t.SkipNow()
|
||||||
|
}
|
||||||
|
testRemoteResource(require.New(t), &test)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRemoteResourceSsh(t *testing.T) {
|
||||||
|
// TODO: add ssh keys to server to run these tests
|
||||||
|
tests := map[string]remoteResourceCase{
|
||||||
|
"scp shorthand": {
|
||||||
|
skip: true,
|
||||||
|
kustomization: `
|
||||||
|
resources:
|
||||||
|
- git@github.com:kubernetes-sigs/kustomize//examples/multibases/dev/?ref=v1.0.6`,
|
||||||
|
expected: multibaseDevExampleBuild,
|
||||||
|
},
|
||||||
|
"full ssh, no ending slash": {
|
||||||
|
skip: true,
|
||||||
|
kustomization: `
|
||||||
|
resources:
|
||||||
|
- ssh://git@github.com/kubernetes-sigs/kustomize//examples/multibases/dev?ref=v1.0.6`,
|
||||||
|
expected: multibaseDevExampleBuild,
|
||||||
|
},
|
||||||
|
"repo": {
|
||||||
|
skip: true,
|
||||||
|
kustomization: `
|
||||||
|
resources:
|
||||||
|
- ssh://git@github.com/annasong20/kustomize-test.git?ref=main`,
|
||||||
|
expected: multibaseDevExampleBuild,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for name, test := range tests {
|
||||||
|
test := test
|
||||||
|
t.Run(name, func(t *testing.T) {
|
||||||
|
if test.skip {
|
||||||
|
t.SkipNow()
|
||||||
|
}
|
||||||
|
testRemoteResource(require.New(t), &test)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRemoteResourcePort(t *testing.T) {
|
||||||
|
sshURL := "ssh://git@github.com:22/kubernetes-sigs/kustomize//examples/multibases/dev/?ref=v1.0.6"
|
||||||
|
httpsURL := "https://github.com:443/kubernetes-sigs/kustomize//examples/multibases/dev/?ref=v1.0.6"
|
||||||
|
|
||||||
|
// TODO: ports not currently supported; implement in future
|
||||||
|
tests := map[string]remoteResourceCase{
|
||||||
|
"ssh": {
|
||||||
|
skip: true,
|
||||||
|
kustomization: fmt.Sprintf(resourcesField, sshURL),
|
||||||
|
error: true,
|
||||||
|
expected: fmt.Sprintf(resourceErrorFormat+fileError, sshURL),
|
||||||
|
},
|
||||||
|
"https": {
|
||||||
|
kustomization: fmt.Sprintf(resourcesField, httpsURL),
|
||||||
|
error: true,
|
||||||
|
expected: fmt.Sprintf(resourceErrorFormat+repoFindError, httpsURL),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for name, test := range tests {
|
||||||
|
test := test
|
||||||
|
t.Run(name, func(t *testing.T) {
|
||||||
|
if test.skip {
|
||||||
|
t.SkipNow()
|
||||||
|
}
|
||||||
|
testRemoteResource(require.New(t), &test)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRemoteResourceRepo(t *testing.T) {
|
||||||
|
tests := map[string]remoteResourceCase{
|
||||||
|
"https, no ref": {
|
||||||
|
// TODO: fix flaky test that sporadically throws errors on server
|
||||||
|
skip: true,
|
||||||
|
kustomization: `
|
||||||
|
resources:
|
||||||
|
- https://github.com/annasong20/kustomize-test.git`,
|
||||||
|
expected: multibaseDevExampleBuild,
|
||||||
|
},
|
||||||
|
"ssh, no ref": {
|
||||||
|
skip: true,
|
||||||
|
kustomization: `
|
||||||
|
resources:
|
||||||
|
- git@github.com:annasong20/kustomize-test.git`,
|
||||||
|
expected: multibaseDevExampleBuild,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for name, test := range tests {
|
||||||
|
test := test
|
||||||
|
t.Run(name, func(t *testing.T) {
|
||||||
|
if test.skip {
|
||||||
|
t.SkipNow()
|
||||||
|
}
|
||||||
|
testRemoteResource(require.New(t), &test)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRemoteResourceParameters(t *testing.T) {
|
||||||
|
httpsNoParam := "https://github.com/kubernetes-sigs/kustomize//examples/multibases/dev/"
|
||||||
|
httpsMasterBranch := "https://github.com/kubernetes-sigs/kustomize//examples/multibases/dev?ref=master"
|
||||||
|
sshNoParams := "git@github.com:kubernetes-sigs/kustomize//examples/multibases/dev"
|
||||||
|
|
||||||
|
// TODO: cases with expected errors are query parameter combinations that aren't supported yet; implement in future
|
||||||
|
// TODO: fix flaky tests (non-ssh tests that we skip) that sporadically fail on server
|
||||||
|
tests := map[string]remoteResourceCase{
|
||||||
|
"https no params": {
|
||||||
|
skip: true,
|
||||||
|
kustomization: fmt.Sprintf(resourcesField, httpsNoParam),
|
||||||
|
error: true,
|
||||||
|
expected: fmt.Sprintf(resourceErrorFormat+repoFindError, httpsNoParam),
|
||||||
|
},
|
||||||
|
"https master": {
|
||||||
|
skip: true,
|
||||||
|
kustomization: fmt.Sprintf(resourcesField, httpsMasterBranch),
|
||||||
|
error: true,
|
||||||
|
expected: fmt.Sprintf(resourceErrorFormat+repoFindError, httpsMasterBranch),
|
||||||
|
},
|
||||||
|
"https master and no submodules": {
|
||||||
|
skip: true,
|
||||||
|
kustomization: `
|
||||||
|
resources:
|
||||||
|
- https://github.com/kubernetes-sigs/kustomize//examples/multibases/dev?ref=master&submodules=false`,
|
||||||
|
expected: multibaseDevExampleBuild,
|
||||||
|
},
|
||||||
|
"https all params": {
|
||||||
|
skip: true,
|
||||||
|
kustomization: `
|
||||||
|
resources:
|
||||||
|
- https://github.com/kubernetes-sigs/kustomize//examples/multibases/dev?ref=v1.0.6&timeout=10&submodules=true`,
|
||||||
|
expected: multibaseDevExampleBuild,
|
||||||
|
},
|
||||||
|
"ssh no params": {
|
||||||
|
skip: true,
|
||||||
|
kustomization: fmt.Sprintf(resourcesField, sshNoParams),
|
||||||
|
error: true,
|
||||||
|
expected: fmt.Sprintf(resourceErrorFormat+fileError, sshNoParams),
|
||||||
|
},
|
||||||
|
"ssh all params": {
|
||||||
|
skip: true,
|
||||||
|
kustomization: `
|
||||||
|
resources:
|
||||||
|
- ssh://git@github.com/annasong20/kustomize-test.git?ref=main&timeout=10&submodules=true`,
|
||||||
|
expected: multibaseDevExampleBuild,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for name, test := range tests {
|
||||||
|
test := test
|
||||||
|
t.Run(name, func(t *testing.T) {
|
||||||
|
if test.skip {
|
||||||
|
t.SkipNow()
|
||||||
|
}
|
||||||
|
testRemoteResource(require.New(t), &test)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRemoteResourceGoGetter(t *testing.T) {
|
||||||
|
// TODO: fix flaky tests (the ones that we skip) that fail sporadically on server
|
||||||
|
tests := map[string]remoteResourceCase{
|
||||||
|
"git detector with / subdirectory separator": {
|
||||||
|
skip: true,
|
||||||
|
kustomization: `
|
||||||
|
resources:
|
||||||
|
- github.com/kubernetes-sigs/kustomize/examples/multibases/dev/?ref=v1.0.6`,
|
||||||
|
expected: multibaseDevExampleBuild,
|
||||||
|
},
|
||||||
|
"git detector for repo": {
|
||||||
|
skip: true,
|
||||||
|
kustomization: `
|
||||||
|
resources:
|
||||||
|
- github.com/annasong20/kustomize-test`,
|
||||||
|
expected: multibaseDevExampleBuild,
|
||||||
|
},
|
||||||
|
"https with / subdirectory separator": {
|
||||||
|
skip: true,
|
||||||
|
kustomization: `
|
||||||
|
resources:
|
||||||
|
- https://github.com/kubernetes-sigs/kustomize/examples/multibases/dev/?ref=v1.0.6`,
|
||||||
|
expected: multibaseDevExampleBuild,
|
||||||
|
},
|
||||||
|
"git forced protocol": {
|
||||||
|
kustomization: `
|
||||||
|
resources:
|
||||||
|
- git::https://github.com/kubernetes-sigs/kustomize//examples/multibases/dev/?ref=v1.0.6`,
|
||||||
|
expected: multibaseDevExampleBuild,
|
||||||
|
},
|
||||||
|
"git forced protocol with / subdirectory separator": {
|
||||||
|
skip: true,
|
||||||
|
kustomization: `
|
||||||
|
resources:
|
||||||
|
- git::https://github.com/kubernetes-sigs/kustomize/examples/multibases/dev/?ref=v1.0.6`,
|
||||||
|
expected: multibaseDevExampleBuild,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for name, test := range tests {
|
||||||
|
test := test
|
||||||
|
t.Run(name, func(t *testing.T) {
|
||||||
|
if test.skip {
|
||||||
|
t.SkipNow()
|
||||||
|
}
|
||||||
|
testRemoteResource(require.New(t), &test)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRemoteResourceWithHttpError(t *testing.T) {
|
||||||
|
require := require.New(t)
|
||||||
|
|
||||||
url404 := "https://github.com/thisisa404.yaml"
|
url404 := "https://github.com/thisisa404.yaml"
|
||||||
kusto := filepath.Join(tmpDir.String(), "kustomization.yaml")
|
fSys, tmpDir := createKustDir(fmt.Sprintf(resourcesField, url404), require)
|
||||||
assert.NoError(t, fSys.WriteFile(kusto, []byte(fmt.Sprintf(`
|
b := krusty.MakeKustomizer(krusty.MakeDefaultOptions())
|
||||||
resources:
|
|
||||||
- %s
|
|
||||||
`, url404))))
|
|
||||||
|
|
||||||
_, err = b.Run(fSys, tmpDir.String())
|
_, err := b.Run(fSys, tmpDir.String())
|
||||||
if utils.IsErrTimeout(err) {
|
|
||||||
// Don't fail on timeouts.
|
|
||||||
t.SkipNow()
|
|
||||||
}
|
|
||||||
|
|
||||||
httpErr := fmt.Errorf("%w: status code %d (%s)", loader.ErrorHTTP, 404, http.StatusText(404))
|
httpErr := fmt.Errorf("%w: status code %d (%s)", loader.ErrorHTTP, 404, http.StatusText(404))
|
||||||
accuFromErr := fmt.Errorf("accumulating resources from '%s': %w", url404, httpErr)
|
accuFromErr := fmt.Errorf("accumulating resources from '%s': %w", url404, httpErr)
|
||||||
expectedErr := fmt.Errorf("accumulating resources: %w", accuFromErr)
|
expectedErr := fmt.Errorf("accumulating resources: %w", accuFromErr)
|
||||||
assert.EqualErrorf(t, err, expectedErr.Error(), url404)
|
require.EqualErrorf(err, expectedErr.Error(), url404)
|
||||||
|
|
||||||
|
require.NoError(fSys.RemoveAll(tmpDir.String()))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRemoteResourceAnnoOrigin(t *testing.T) {
|
func TestRemoteResourceAnnoOrigin(t *testing.T) {
|
||||||
fSys := filesys.MakeFsOnDisk()
|
test := remoteResourceCase{
|
||||||
b := krusty.MakeKustomizer(krusty.MakeDefaultOptions())
|
kustomization: `
|
||||||
tmpDir, err := filesys.NewTmpConfirmedDir()
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.NoError(t, fSys.WriteFile(filepath.Join(tmpDir.String(), "kustomization.yaml"), []byte(`
|
|
||||||
resources:
|
resources:
|
||||||
- github.com/kubernetes-sigs/kustomize/examples/multibases/dev/?ref=v1.0.6
|
- github.com/kubernetes-sigs/kustomize/examples/multibases/dev/?ref=v1.0.6
|
||||||
buildMetadata: [originAnnotations]
|
buildMetadata: [originAnnotations]
|
||||||
`)))
|
`,
|
||||||
m, err := b.Run(
|
expected: `apiVersion: v1
|
||||||
fSys,
|
|
||||||
tmpDir.String())
|
|
||||||
if utils.IsErrTimeout(err) {
|
|
||||||
// Don't fail on timeouts.
|
|
||||||
t.SkipNow()
|
|
||||||
}
|
|
||||||
assert.NoError(t, err)
|
|
||||||
yml, err := m.AsYaml()
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.Equal(t, `apiVersion: v1
|
|
||||||
kind: Pod
|
kind: Pod
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
annotations:
|
||||||
@@ -137,24 +372,28 @@ spec:
|
|||||||
containers:
|
containers:
|
||||||
- image: nginx:1.7.9
|
- image: nginx:1.7.9
|
||||||
name: nginx
|
name: nginx
|
||||||
`, string(yml))
|
`,
|
||||||
assert.NoError(t, fSys.RemoveAll(tmpDir.String()))
|
}
|
||||||
|
|
||||||
|
testRemoteResource(require.New(t), &test)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRemoteResourceAsBaseWithAnnoOrigin(t *testing.T) {
|
func TestRemoteResourceAsBaseWithAnnoOrigin(t *testing.T) {
|
||||||
|
require := require.New(t)
|
||||||
|
|
||||||
fSys := filesys.MakeFsOnDisk()
|
fSys := filesys.MakeFsOnDisk()
|
||||||
b := krusty.MakeKustomizer(krusty.MakeDefaultOptions())
|
b := krusty.MakeKustomizer(krusty.MakeDefaultOptions())
|
||||||
tmpDir, err := filesys.NewTmpConfirmedDir()
|
tmpDir, err := filesys.NewTmpConfirmedDir()
|
||||||
assert.NoError(t, err)
|
require.NoError(err)
|
||||||
base := filepath.Join(tmpDir.String(), "base")
|
base := filepath.Join(tmpDir.String(), "base")
|
||||||
prod := filepath.Join(tmpDir.String(), "prod")
|
prod := filepath.Join(tmpDir.String(), "prod")
|
||||||
assert.NoError(t, fSys.Mkdir(base))
|
require.NoError(fSys.Mkdir(base))
|
||||||
assert.NoError(t, fSys.Mkdir(prod))
|
require.NoError(fSys.Mkdir(prod))
|
||||||
assert.NoError(t, fSys.WriteFile(filepath.Join(base, "kustomization.yaml"), []byte(`
|
require.NoError(fSys.WriteFile(filepath.Join(base, "kustomization.yaml"), []byte(`
|
||||||
resources:
|
resources:
|
||||||
- github.com/kubernetes-sigs/kustomize/examples/multibases/dev/?ref=v1.0.6
|
- github.com/kubernetes-sigs/kustomize/examples/multibases/dev/?ref=v1.0.6
|
||||||
`)))
|
`)))
|
||||||
assert.NoError(t, fSys.WriteFile(filepath.Join(prod, "kustomization.yaml"), []byte(`
|
require.NoError(fSys.WriteFile(filepath.Join(prod, "kustomization.yaml"), []byte(`
|
||||||
resources:
|
resources:
|
||||||
- ../base
|
- ../base
|
||||||
namePrefix: prefix-
|
namePrefix: prefix-
|
||||||
@@ -164,14 +403,9 @@ buildMetadata: [originAnnotations]
|
|||||||
m, err := b.Run(
|
m, err := b.Run(
|
||||||
fSys,
|
fSys,
|
||||||
prod)
|
prod)
|
||||||
if utils.IsErrTimeout(err) {
|
require.NoError(err)
|
||||||
// Don't fail on timeouts.
|
|
||||||
t.SkipNow()
|
expected := `apiVersion: v1
|
||||||
}
|
|
||||||
assert.NoError(t, err)
|
|
||||||
yml, err := m.AsYaml()
|
|
||||||
assert.NoError(t, err)
|
|
||||||
assert.Equal(t, `apiVersion: v1
|
|
||||||
kind: Pod
|
kind: Pod
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
annotations:
|
||||||
@@ -186,6 +420,8 @@ spec:
|
|||||||
containers:
|
containers:
|
||||||
- image: nginx:1.7.9
|
- image: nginx:1.7.9
|
||||||
name: nginx
|
name: nginx
|
||||||
`, string(yml))
|
`
|
||||||
assert.NoError(t, fSys.RemoveAll(tmpDir.String()))
|
checkYaml(m, expected, require)
|
||||||
|
|
||||||
|
require.NoError(fSys.RemoveAll(tmpDir.String()))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -172,6 +172,5 @@ spec:
|
|||||||
// containers:
|
// containers:
|
||||||
// - image: image-canary-a
|
// - image: image-canary-a
|
||||||
// name: container-a
|
// name: container-a
|
||||||
//`)
|
// `)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// Copyright 2022 The Kubernetes Authors.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
package krusty_test
|
package krusty_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -110,6 +113,67 @@ spec:
|
|||||||
th.AssertActualEqualsExpected(m, expected)
|
th.AssertActualEqualsExpected(m, expected)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestReplacementsFieldWithPathMultiple(t *testing.T) {
|
||||||
|
th := kusttest_test.MakeEnhancedHarness(t)
|
||||||
|
defer th.Reset()
|
||||||
|
|
||||||
|
th.WriteK(".", `
|
||||||
|
resources:
|
||||||
|
- resource.yaml
|
||||||
|
|
||||||
|
replacements:
|
||||||
|
- path: replacement.yaml
|
||||||
|
`)
|
||||||
|
th.WriteF("replacement.yaml", `
|
||||||
|
- source:
|
||||||
|
kind: Deployment
|
||||||
|
fieldPath: spec.template.spec.containers.0.image
|
||||||
|
targets:
|
||||||
|
- select:
|
||||||
|
kind: Deployment
|
||||||
|
fieldPaths:
|
||||||
|
- spec.template.spec.containers.1.image
|
||||||
|
- source:
|
||||||
|
kind: Deployment
|
||||||
|
fieldPath: spec.template.spec.containers.0.name
|
||||||
|
targets:
|
||||||
|
- select:
|
||||||
|
kind: Deployment
|
||||||
|
fieldPaths:
|
||||||
|
- spec.template.spec.containers.1.name
|
||||||
|
`)
|
||||||
|
th.WriteF("resource.yaml", `
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: deploy
|
||||||
|
spec:
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- image: foobar:1
|
||||||
|
name: replaced-with-digest
|
||||||
|
- image: postgres:1.8.0
|
||||||
|
name: postgresdb
|
||||||
|
`)
|
||||||
|
expected := `
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: deploy
|
||||||
|
spec:
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- image: foobar:1
|
||||||
|
name: replaced-with-digest
|
||||||
|
- image: foobar:1
|
||||||
|
name: replaced-with-digest
|
||||||
|
`
|
||||||
|
m := th.Run(".", th.MakeDefaultOptions())
|
||||||
|
th.AssertActualEqualsExpected(m, expected)
|
||||||
|
}
|
||||||
|
|
||||||
func TestReplacementTransformerWithDiamondShape(t *testing.T) {
|
func TestReplacementTransformerWithDiamondShape(t *testing.T) {
|
||||||
th := kusttest_test.MakeEnhancedHarness(t)
|
th := kusttest_test.MakeEnhancedHarness(t)
|
||||||
defer th.Reset()
|
defer th.Reset()
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// Copyright 2022 The Kubernetes Authors.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
package krusty_test
|
package krusty_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// Copyright 2022 The Kubernetes Authors.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
package krusty_test
|
package krusty_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|||||||
20
api/krusty/testdata/localize/simple/deployment.yaml
vendored
Normal file
20
api/krusty/testdata/localize/simple/deployment.yaml
vendored
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: test-deployment-simple
|
||||||
|
labels:
|
||||||
|
app: deployment-simple
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: simple
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: simple
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: nginx
|
||||||
|
image: nginx:1.16
|
||||||
|
ports:
|
||||||
|
- containerPort: 8080
|
||||||
8
api/krusty/testdata/localize/simple/kustomization.yaml
vendored
Normal file
8
api/krusty/testdata/localize/simple/kustomization.yaml
vendored
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
|
kind: Kustomization
|
||||||
|
|
||||||
|
resources:
|
||||||
|
- ./deployment.yaml
|
||||||
|
- ./service.yaml
|
||||||
|
|
||||||
|
namePrefix: localize-
|
||||||
11
api/krusty/testdata/localize/simple/service.yaml
vendored
Normal file
11
api/krusty/testdata/localize/simple/service.yaml
vendored
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: test-service-simple
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app: deployment-simple
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: 80
|
||||||
|
targetPort: 8080
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
|
// Copyright 2022 The Kubernetes Authors.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
package loader
|
package loader
|
||||||
|
|
||||||
import "fmt"
|
import "fmt"
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user