mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-06-15 02:48:16 +00:00
Compare commits
257 Commits
api/v0.13.
...
release-ap
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5497967665 | ||
|
|
0115ae6da4 | ||
|
|
bb5022441a | ||
|
|
8668b74622 | ||
|
|
752bb2ef41 | ||
|
|
bde28b1320 | ||
|
|
689dcefa3a | ||
|
|
f3e263a051 | ||
|
|
fa48ab16bf | ||
|
|
0eca5c4b06 | ||
|
|
6b76c807f5 | ||
|
|
76695414c7 | ||
|
|
d64ac13447 | ||
|
|
f80d9c41e5 | ||
|
|
2f99707792 | ||
|
|
7a08dde7ac | ||
|
|
81297df4ff | ||
|
|
c4137c0c2a | ||
|
|
944c72a275 | ||
|
|
46e2d72213 | ||
|
|
6cb85e8544 | ||
|
|
6ef9773c02 | ||
|
|
11aa57e67f | ||
|
|
779f153071 | ||
|
|
60d7ee6710 | ||
|
|
852739c477 | ||
|
|
bee2e5f50c | ||
|
|
ace2d53b18 | ||
|
|
aeb7cb2a40 | ||
|
|
713842330e | ||
|
|
5936a892a7 | ||
|
|
c3a4f3eab6 | ||
|
|
fb7ee2f487 | ||
|
|
45e57f0228 | ||
|
|
9920586b22 | ||
|
|
61dad14345 | ||
|
|
f65506d285 | ||
|
|
cbbd1599f2 | ||
|
|
4b34ff3075 | ||
|
|
654d7953d9 | ||
|
|
d91ea65f5a | ||
|
|
7911b2c001 | ||
|
|
0d854a5144 | ||
|
|
cb5b241715 | ||
|
|
039b05fb16 | ||
|
|
9c1d412dac | ||
|
|
a318d4db26 | ||
|
|
0cfafddacc | ||
|
|
f5ca753377 | ||
|
|
0d4849ff98 | ||
|
|
e3b9afcfaa | ||
|
|
af781bfa5e | ||
|
|
7dd9637b1a | ||
|
|
ddce57b585 | ||
|
|
11fc419cee | ||
|
|
a8dec66a84 | ||
|
|
7e541ca380 | ||
|
|
1bd58bdc15 | ||
|
|
9107fa3c81 | ||
|
|
df0cd3c4a3 | ||
|
|
f3b34c44b5 | ||
|
|
9e101ee97f | ||
|
|
433be59ea7 | ||
|
|
2c444d6bf4 | ||
|
|
a90c19d577 | ||
|
|
8f283499e9 | ||
|
|
d78fe665a7 | ||
|
|
532abf77e7 | ||
|
|
59696d1ace | ||
|
|
d30e457031 | ||
|
|
ae041b5c54 | ||
|
|
a2b60e4bcb | ||
|
|
9d126f6dd8 | ||
|
|
bd8045b648 | ||
|
|
5c1a022a3c | ||
|
|
e19ca5405a | ||
|
|
56d37acc7d | ||
|
|
0571a2f15d | ||
|
|
0cdfa5b3dc | ||
|
|
7c36ed21b3 | ||
|
|
985835f96f | ||
|
|
f81765b96e | ||
|
|
a2ceaff053 | ||
|
|
94181b1be7 | ||
|
|
169fdd7330 | ||
|
|
78b8139d46 | ||
|
|
76f8d2828b | ||
|
|
b692e49b1e | ||
|
|
bd7f001c26 | ||
|
|
d6ff768298 | ||
|
|
4947a905fa | ||
|
|
cd9a16cfab | ||
|
|
02a53f193d | ||
|
|
b1717c8a97 | ||
|
|
911ddcda40 | ||
|
|
daf06622a2 | ||
|
|
9f1d5acdc8 | ||
|
|
9756d92a91 | ||
|
|
d32d1937e6 | ||
|
|
ddcbae54ab | ||
|
|
ca748faa3f | ||
|
|
5e6cbac589 | ||
|
|
ff75dd6cd5 | ||
|
|
f8391994b4 | ||
|
|
5ce14e5024 | ||
|
|
ee22c9cab7 | ||
|
|
4a893ce8c6 | ||
|
|
9ce923ebeb | ||
|
|
494a807f28 | ||
|
|
820f17c73b | ||
|
|
cd7ba1744e | ||
|
|
da4e881007 | ||
|
|
878cda7c55 | ||
|
|
47327616df | ||
|
|
eeff67d88d | ||
|
|
6adf4f294a | ||
|
|
5e7cc3437d | ||
|
|
ded76df3af | ||
|
|
d7362ed22d | ||
|
|
4711bfe40c | ||
|
|
8c0e0b3b47 | ||
|
|
096b2c4435 | ||
|
|
129d0f90af | ||
|
|
c76fd5eb85 | ||
|
|
9e42f8d57e | ||
|
|
168e31bfb6 | ||
|
|
691b7d1df3 | ||
|
|
336bc14e1a | ||
|
|
b2c39b61bb | ||
|
|
da31b966fb | ||
|
|
dce94267fb | ||
|
|
d1647a51af | ||
|
|
5b76aa9d2f | ||
|
|
0add0f95e2 | ||
|
|
6ce0bf390c | ||
|
|
7c98e531f2 | ||
|
|
e1ab8c79c1 | ||
|
|
cf3e81b590 | ||
|
|
565cff2d07 | ||
|
|
8383b28322 | ||
|
|
e1c530e420 | ||
|
|
035924bc1e | ||
|
|
fd508f0e3a | ||
|
|
9407e26433 | ||
|
|
3cac8448d3 | ||
|
|
84642b1fed | ||
|
|
fa574866b4 | ||
|
|
4b807107a6 | ||
|
|
6bb62dd6ef | ||
|
|
3d6f40bd5e | ||
|
|
c2bd42e774 | ||
|
|
529a25d30b | ||
|
|
ccdc148472 | ||
|
|
7dcb2a50ff | ||
|
|
1e3215226e | ||
|
|
459d0198d9 | ||
|
|
3abf91644e | ||
|
|
1f98338481 | ||
|
|
91078545e6 | ||
|
|
467633c2de | ||
|
|
e44df7b386 | ||
|
|
bbff6768da | ||
|
|
0020a496f7 | ||
|
|
5a3e920902 | ||
|
|
96f893f350 | ||
|
|
97c8cd7d1a | ||
|
|
ee3f506d10 | ||
|
|
0f244a4a07 | ||
|
|
c79916b1ba | ||
|
|
2ce1c7cce3 | ||
|
|
75fa235498 | ||
|
|
7413c6a5fb | ||
|
|
315ed56450 | ||
|
|
9eddc3c5a7 | ||
|
|
38d5bf8e09 | ||
|
|
85d623bc86 | ||
|
|
928b823d8f | ||
|
|
2c2b2ab825 | ||
|
|
d3184da4c6 | ||
|
|
eadb469712 | ||
|
|
2649d39fd3 | ||
|
|
faab836ec9 | ||
|
|
c9f500cc0b | ||
|
|
42bf3c0e2b | ||
|
|
3b395a9da2 | ||
|
|
633da991d2 | ||
|
|
e07b8a5d15 | ||
|
|
71a7a7df13 | ||
|
|
436a047617 | ||
|
|
4d70a36c25 | ||
|
|
304d0e951f | ||
|
|
2fdb35614d | ||
|
|
5dff9df1f7 | ||
|
|
84682a1159 | ||
|
|
c151147258 | ||
|
|
317fcadccb | ||
|
|
a2e9682002 | ||
|
|
5dcf0ae683 | ||
|
|
ce3e394a41 | ||
|
|
0c92647760 | ||
|
|
39527da73c | ||
|
|
fa90046136 | ||
|
|
efe1374940 | ||
|
|
b751ffe5a0 | ||
|
|
28a2a01c29 | ||
|
|
0c650423ed | ||
|
|
4ffc861854 | ||
|
|
8338873e56 | ||
|
|
dd520f8889 | ||
|
|
4842d8be60 | ||
|
|
bf6e6ad33b | ||
|
|
e1094da3cf | ||
|
|
7d150ce973 | ||
|
|
39264a7057 | ||
|
|
736e166168 | ||
|
|
e8b521e3ab | ||
|
|
694b3c9318 | ||
|
|
a4954d386a | ||
|
|
976193ce70 | ||
|
|
ee0b26601b | ||
|
|
78e310231e | ||
|
|
ffa554b371 | ||
|
|
68a0fc95da | ||
|
|
9b43e76947 | ||
|
|
adf760e246 | ||
|
|
7a89df8350 | ||
|
|
93d7511b38 | ||
|
|
7c33fe30b7 | ||
|
|
cd49194383 | ||
|
|
22dbd3eb17 | ||
|
|
53a4134379 | ||
|
|
51e2714408 | ||
|
|
d825beff27 | ||
|
|
aa4eb59bb0 | ||
|
|
00d450cce7 | ||
|
|
a090ceac6c | ||
|
|
63c37b1780 | ||
|
|
dfd2d7600d | ||
|
|
0fd385d719 | ||
|
|
57d8583887 | ||
|
|
9c116e9031 | ||
|
|
e6c16a6ddc | ||
|
|
03669a1804 | ||
|
|
3c44db8746 | ||
|
|
9a1a203b52 | ||
|
|
8b51c295a1 | ||
|
|
738ca56ccd | ||
|
|
f901b4a5fd | ||
|
|
4fff8399ea | ||
|
|
e532d6f1a1 | ||
|
|
db2a3800ed | ||
|
|
183928e6ba | ||
|
|
c0e2030905 | ||
|
|
87c428e7cd | ||
|
|
f5ad795995 | ||
|
|
ffd45f6893 | ||
|
|
7aa33ff471 |
36
.github/workflows/apidiff.yml
vendored
Normal file
36
.github/workflows/apidiff.yml
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
name: APIDiff
|
||||
|
||||
# Trigger the workflow on pull requests and direct pushes to any branch
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
go-apidiff:
|
||||
name: Verify API differences
|
||||
runs-on: ubuntu-latest
|
||||
# Pull requests from different repository only trigger this checks
|
||||
if: (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository)
|
||||
steps:
|
||||
- name: Clone the code
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v4
|
||||
with:
|
||||
go-version-file: go.work
|
||||
- name: Execute go-apidiff
|
||||
uses: joelanford/go-apidiff@v0.6.0
|
||||
with:
|
||||
compare-imports: true
|
||||
print-compatible: true
|
||||
- name: Report failure
|
||||
uses: nashmaniac/create-issue-action@v1.2
|
||||
# Only report failures of pushes (PRs have are visible through the Checks section) to the default branch
|
||||
if: failure() && github.event_name == 'push' && github.ref == 'refs/heads/master'
|
||||
with:
|
||||
title: 🐛 go-apidiff failed for ${{ github.sha }}
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
labels: kind/bug
|
||||
body: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
||||
109
.github/workflows/go.yml
vendored
109
.github/workflows/go.yml
vendored
@@ -10,26 +10,21 @@ permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
|
||||
lint:
|
||||
name: Lint
|
||||
runs-on: [ubuntu-latest]
|
||||
steps:
|
||||
|
||||
- name: Set up Go 1.x
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: '^1.19.0'
|
||||
id: go
|
||||
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up Go 1.x
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version-file: go.work
|
||||
id: go
|
||||
- name: Lint
|
||||
run: make lint
|
||||
|
||||
- name: Verify boilerplate
|
||||
run: make check-license
|
||||
|
||||
@@ -37,66 +32,56 @@ jobs:
|
||||
name: Test Linux
|
||||
runs-on: [ubuntu-latest]
|
||||
steps:
|
||||
|
||||
- name: Set up Go 1.x
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: '^1.19.0'
|
||||
id: go
|
||||
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Test all modules
|
||||
run: make test-unit-non-plugin
|
||||
env:
|
||||
KUSTOMIZE_DOCKER_E2E: true
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@v3
|
||||
- name: Set up Go 1.x
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version-file: go.work
|
||||
id: go
|
||||
- name: Test all modules
|
||||
run: make test-unit-non-plugin
|
||||
env:
|
||||
KUSTOMIZE_DOCKER_E2E: true
|
||||
|
||||
test-macos:
|
||||
name: Test MacOS
|
||||
runs-on: [macos-latest]
|
||||
steps:
|
||||
|
||||
- name: Set up Go 1.x
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: '^1.19.0'
|
||||
id: go
|
||||
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Test all modules
|
||||
run: make test-unit-non-plugin
|
||||
env:
|
||||
KUSTOMIZE_DOCKER_E2E: false # docker not installed on mac
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@v3
|
||||
- name: Set up Go 1.x
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version-file: go.work
|
||||
id: go
|
||||
- name: Test all modules
|
||||
run: make test-unit-non-plugin
|
||||
env:
|
||||
KUSTOMIZE_DOCKER_E2E: false # docker not installed on mac
|
||||
|
||||
test-windows:
|
||||
name: Test Windows
|
||||
runs-on: [windows-latest]
|
||||
steps:
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@v3
|
||||
- name: Set up Go 1.x
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version-file: go.work
|
||||
id: go
|
||||
- name: Test kyaml
|
||||
run: go test -cover ./...
|
||||
working-directory: ./kyaml
|
||||
- name: Test cmd/config
|
||||
run: go test -cover ./...
|
||||
working-directory: ./cmd/config
|
||||
env:
|
||||
KUSTOMIZE_DOCKER_E2E: false # docker on windows not working well yet
|
||||
|
||||
- name: Set up Go 1.x
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: '^1.19.0'
|
||||
id: go
|
||||
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Test kyaml
|
||||
run: go test -cover ./...
|
||||
working-directory: ./kyaml
|
||||
|
||||
- name: Test cmd/config
|
||||
run: go test -cover ./...
|
||||
working-directory: ./cmd/config
|
||||
env:
|
||||
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
|
||||
# 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
|
||||
|
||||
27
.github/workflows/release.yaml
vendored
Normal file
27
.github/workflows/release.yaml
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
name: release
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- kyaml/v*
|
||||
- cmd/config/v*
|
||||
- api/v*
|
||||
- kustomize/v*
|
||||
|
||||
jobs:
|
||||
release:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Set up Go 1.x
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version-file: go.work
|
||||
id: go
|
||||
- run: ./releasing/create-release.sh "${tag}"
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
tag: ${{ github.ref_name }}
|
||||
117
.golangci.yml
117
.golangci.yml
@@ -3,96 +3,37 @@
|
||||
|
||||
run:
|
||||
deadline: 5m
|
||||
go: '1.19'
|
||||
go: '1.20'
|
||||
|
||||
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
|
||||
- depguard
|
||||
- dogsled
|
||||
- dupl
|
||||
- dupword
|
||||
- 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
|
||||
# - stylecheck
|
||||
- tagliatelle
|
||||
- tenv
|
||||
- testpackage
|
||||
- testableexamples
|
||||
- thelper
|
||||
- tparallel
|
||||
- typecheck
|
||||
- unconvert
|
||||
- unparam
|
||||
- unused
|
||||
# - varnamelen
|
||||
- wastedassign
|
||||
- whitespace
|
||||
- wrapcheck
|
||||
# - wsl
|
||||
- asasalint
|
||||
- usestdlibvars
|
||||
- interfacebloat
|
||||
- loggercheck
|
||||
- reassign
|
||||
enable-all: true
|
||||
disable:
|
||||
- cyclop
|
||||
- exhaustivestruct
|
||||
- forbidigo
|
||||
- funlen
|
||||
- gci
|
||||
- gocognit
|
||||
- godot
|
||||
- godox
|
||||
- goerr113
|
||||
- gofumpt
|
||||
- ifshort # too many false positives
|
||||
- ireturn
|
||||
- nilnil
|
||||
- nlreturn
|
||||
- noctx
|
||||
- paralleltest
|
||||
- stylecheck
|
||||
- varnamelen
|
||||
- wsl
|
||||
- exhaustruct
|
||||
- deadcode
|
||||
- scopelint
|
||||
- nonamedreturns
|
||||
- golint
|
||||
- maintidx
|
||||
- nosnakecase
|
||||
|
||||
linters-settings:
|
||||
dupl:
|
||||
|
||||
129
CONTRIBUTING.md
129
CONTRIBUTING.md
@@ -59,11 +59,140 @@ Kustomize follows the [Kubernetes Community Membership] contributor ladder. Role
|
||||
|
||||
The kyaml module within the Kustomize repo has additional owners following the same ladder.
|
||||
|
||||
For the kustomize project, we have defined some specific guidelines on each step of the ladder:
|
||||
|
||||
To reach reviewer status, you must:
|
||||
- Have been actively involved in kustomize for 3+ months
|
||||
- Review at least 8 PRs that have been driven through to completion (see the reviewer guide below)
|
||||
- Author at least 5 PRs that have been approved and merged
|
||||
- Be a member of the kubernetes-sigs org. This should not be a blocker though, as once you meet the requirements for reviewer here,
|
||||
the existing kustomize maintainers will be happy to sponsor your request to join the kubernetes-sigs org.
|
||||
- Once you have met the above requirements, you may submit a PR adding yourself to the kustomize reviewers list, with links to your
|
||||
contributions in the description.
|
||||
|
||||
To reach approver status, you must:
|
||||
- Meet all the requirements of a reviewer
|
||||
- Have been actively involved in kustomize for 6+ months
|
||||
- Review at least 15 PRs that have been driven through to completion (see the reviewer guide below)
|
||||
- Authored PRs meeting *either* of the following requirements:
|
||||
- 15 PRs that have been approved and merged
|
||||
- *OR* 10 PRs that have been approved and merged where some were more difficult, required greater thought/design,
|
||||
or built up to larger features/long-term goals.
|
||||
- File 3 issues. This can be any number of things, including but not limited to:
|
||||
- Bugs with kustomize usage that you've found
|
||||
- CI or release improvements
|
||||
- Creating subtasks of a larger feature or project that you are in charge of.
|
||||
- Long term improvements for the health of the project
|
||||
- Triage at least 10 untriaged issues, including at least 1 feature request. The kustomize bug scrub is a great place to get practice with doing this, but you can
|
||||
also follow the triage guide below to get started on your own.
|
||||
- Demonstrate deeper understanding of kustomize goals. This can take many forms and is a bit subjective, but here are a few examples:
|
||||
- saying no to an eschewed feature, instead recommending an alternative solution that is more aligned with the declarative configuration model
|
||||
- active participation in discussion on a feature request issue
|
||||
- filing an issue describing a long term problem and solution aligned with kustomize goals, for example: https://github.com/kubernetes-sigs/kustomize/issues/5140
|
||||
- writing up KEPs for features that will improve the kustomize workflow while being aligned with kustomize goals, for example: https://github.com/kubernetes-sigs/kustomize/pull/4558
|
||||
- Regularly interact with the existing kustomize maintainers, with clear communication about what you are working on or planning to work on. The kustomize
|
||||
maintainers should know who you are and be familiar with your contributions.
|
||||
- If you meet *most* of the above requirements while going above and beyond in a few areas, we will still consider your request to become an approver even
|
||||
if you are missing one or two of the requirements. Please contact the maintainers directly to ask about getting approver status if you fall into this category.
|
||||
- Otherwise, once you meet all the above requirements, you may:
|
||||
- request to be added to the kustomize maintainer meeting that occurs each week with the kustomize PMs.
|
||||
- submit a PR adding yourself to the kustomize approvers list, with links to your contributions in the description.
|
||||
|
||||
To reach owner status, you must:
|
||||
- Meet all the requirements of an approver
|
||||
- Have been actively involved with kustomize for 1+ year
|
||||
- Assisted the current owner in driving the roadmap. This can be explicit or implicit help, such as:
|
||||
- Editing the roadmap directly
|
||||
- Reviewing the roadmap
|
||||
- Providing suggestions for issues or prioritization in meetings that indirectly influence the roadmap
|
||||
- Regularly triage issues and attend the kustomize bug scrub
|
||||
- Regularly review PRs (1-2 a week)
|
||||
- Periodically lead the kustomize bug scrub
|
||||
- Periodically release kustomize (ensuring that there are no release blockers and that release notes are clean)
|
||||
- Be the primary owner or point of contact for a particular project or area of code
|
||||
- Ideally, there should be 2-3 owners at a time. Reach out to the current owners if you are interested in ownership. These
|
||||
requirements are not strict and evaluation is somewhat subjective.
|
||||
|
||||
## Reviewer guide
|
||||
Please watch this talk on how to review code from Tim Hockin: https://www.youtube.com/watch?v=OZVv7-o8i40
|
||||
|
||||
For reviewing PRs in kustomize, we have some specific guidelines:
|
||||
- If the PR is introducing a new feature:
|
||||
- *It must be implementing an issue that has already been triage/accepted or
|
||||
a KEP that has been approved.* If it is not, then request the PR author to first file an issue.
|
||||
- The PR must include thorough tests for the new feature, including unit and integration tests
|
||||
- The code must be clean and readable, with thought given to how we will maintain the code in the future
|
||||
- If the feature requires being broken up into multiple PRs to ease review, the feature should not be exposed to users
|
||||
until the feature is completed in the last PR. For example, while we were building `kustomize localize`, we
|
||||
built the feature almost entirely under the `api` module as a library with all the needed tests. There was no way
|
||||
for users to invoke the localize code until the last PR that actually exposed the `kustomize localize` command in the
|
||||
kustomize binary. This allowed us to continue development of `kustomize localize` without blocking kustomize releases.
|
||||
If this type of development is not possible, then new features requiring multiple PRs should be
|
||||
developed in their own feature branch.
|
||||
- If the PR is introducing a bug fix:
|
||||
- If the PR is not fixing an issue that has already been triage/accepted, follow the triage guide below on bug
|
||||
fixes to decide if this is a PR we want to accept.
|
||||
- The PR should have two distinct commits:
|
||||
- The first commit should add a test demonstrating incorrect behavior
|
||||
- The second commit should include the bug fix
|
||||
- Some sample PRs:
|
||||
- https://github.com/kubernetes-sigs/kustomize/pull/5263/commits
|
||||
- https://github.com/kubernetes-sigs/kustomize/pull/3931/commits
|
||||
- The regression test is absolutely required, and we cannot accept bug fixes without tests.
|
||||
- If the PR is introducing a performance improvement:
|
||||
- The PR description should give an indication of how much the performance is being improved and how we
|
||||
can measure it - benchmark tests are fantastic.
|
||||
- Other PRs (documentation, CI improvements, etc.) should be reviewed based on your best judgment.
|
||||
|
||||
## Triage guide
|
||||
The possible triage labels are listed here: https://github.com/kubernetes-sigs/kustomize/labels?q=triage.
|
||||
|
||||
Triaging a feature request means:
|
||||
- Understand what the user is asking for, and their use case.
|
||||
- Verify that it is not an [eschewed feature](https://kubectl.docs.kubernetes.io/faq/kustomize/eschewedfeatures/#build-time-side-effects-from-cli-args-or-env-variables)
|
||||
- Verify that it is not a duplicate issue.
|
||||
- Look into workarounds. Is there another way that the user can achieve their use case with existing features?
|
||||
- If you are new to this role, prior to leaving a comment on the issue, please bring it to weekly standup
|
||||
for group discussion to make sure that we are all on the same page.
|
||||
- Once you feel ready, you can label it with a triage label. Here's an [example](https://github.com/kubernetes-sigs/kustomize/issues/5049). You can also
|
||||
look at other feature request issues to see how they were triaged and resolved. There are a few different triage labels that you can use, you can see the
|
||||
full list [here](https://github.com/kubernetes-sigs/kustomize/labels?q=triage).
|
||||
|
||||
Triaging a bug means:
|
||||
- First, verify that you can reproduce the issue. If you cannot reproduce the issue or need more information to give
|
||||
it a go, triage it accordingly.
|
||||
- Try to understand if this is really a bug or if this is intended behavior from kustomize. If it seems like intended
|
||||
behavior, do your best to explain to the user why this is the case.
|
||||
- If it seems to be a genuine bug, you can /triage accept the issue. In addition, investigate if there are workarounds or
|
||||
alternative solutions for the user that they can try until the issue gets resolved.
|
||||
|
||||
Administrative notes:
|
||||
|
||||
- The [OWNERS file spec] is a useful resources in making changes.
|
||||
- Maintainers and admins must be added to the appropriate lists in both [Kustomize OWNERS_ALIASES] and [SIG-CLI Teams]. If this isn't done, the individual in question will lack either PR approval rights (Kustomize list) or the appropriate Github repository permissions (community list).
|
||||
|
||||
## Project/Product Managers
|
||||
|
||||
Kustomize will have opportunities to join in a project/product manager role. You can reach out to
|
||||
the existing kustomize maintainers if you are interested in this type of role. Project management work
|
||||
can greatly help supplement your contributions as you climb from reviewer to approver
|
||||
to owner.
|
||||
|
||||
Expectations for this role are:
|
||||
|
||||
- Triage 1 feature request each week, and bring it to weekly stand-up for discussion. Feature
|
||||
requests are issues labeled kind/feature, and you can find them [here](https://github.com/kubernetes-sigs/kustomize/issues?q=is%3Aissue+is%3Aopen+kind+feature+label%3Akind%2Ffeature).
|
||||
Please view the above triage guide for details on how to approach feature request triage.
|
||||
- Monitor the kustomize Slack channel and try to help users if you can. It is a pretty
|
||||
active channel, so responding to 4-5 users per week is sufficient even if some
|
||||
questions go unanswered. If there is an interesting topic or a recurring problem that many
|
||||
users are having, please bring it up in weekly stand-up.
|
||||
- Keeping track of a queue of backlog issues or PRs that are not being actively looked at in any existing project board.
|
||||
- Organizing or reorganizing project tracking boards when it makes sense.
|
||||
|
||||
You will also be asked to help with roadmap planning, deprecation communication, prioritization,
|
||||
and doing research on kustomize usage when appropriate, though these responsibilities will occur less
|
||||
frequently.
|
||||
|
||||
## Contact Information
|
||||
|
||||
|
||||
34
Makefile
34
Makefile
@@ -3,7 +3,7 @@
|
||||
#
|
||||
# Makefile for kustomize CLI and API.
|
||||
|
||||
LATEST_V4_RELEASE=v4.5.6
|
||||
LATEST_RELEASE=v5.1.1
|
||||
|
||||
SHELL := /usr/bin/env bash
|
||||
GOOS = $(shell go env GOOS)
|
||||
@@ -101,18 +101,21 @@ verify-kustomize-repo: \
|
||||
build-non-plugin-all \
|
||||
test-go-mod \
|
||||
test-examples-kustomize-against-HEAD \
|
||||
test-examples-kustomize-against-v4-release
|
||||
test-examples-kustomize-against-latest-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 \
|
||||
workspace-sync \
|
||||
generate-kustomize-builtin-plugins \
|
||||
builtin-plugins-diff \
|
||||
test-unit-kustomize-plugins \
|
||||
test-go-mod \
|
||||
build-non-plugin-all \
|
||||
test-examples-kustomize-against-HEAD \
|
||||
test-examples-kustomize-against-v4-release
|
||||
test-examples-kustomize-against-latest-release
|
||||
|
||||
.PHONY: license
|
||||
license: $(MYGOBIN)/addlicense
|
||||
@@ -126,6 +129,14 @@ check-license: $(MYGOBIN)/addlicense
|
||||
lint: $(MYGOBIN)/golangci-lint $(MYGOBIN)/goimports $(builtinplugins)
|
||||
./hack/for-each-module.sh "make lint"
|
||||
|
||||
.PHONY: apidiff
|
||||
apidiff: go-apidiff ## Run the go-apidiff to verify any API differences compared with origin/master
|
||||
$(GOBIN)/go-apidiff master --compare-imports --print-compatible --repo-path=.
|
||||
|
||||
.PHONY: go-apidiff
|
||||
go-apidiff:
|
||||
go install github.com/joelanford/go-apidiff@v0.6.0
|
||||
|
||||
.PHONY: test-unit-all
|
||||
test-unit-all: \
|
||||
test-unit-non-plugin \
|
||||
@@ -134,11 +145,11 @@ test-unit-all: \
|
||||
# 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
|
||||
./hack/for-each-module.sh "make test" "./plugin/*" 16
|
||||
|
||||
.PHONY: build-non-plugin-all
|
||||
build-non-plugin-all:
|
||||
./hack/for-each-module.sh "make build" "./plugin/*" 15
|
||||
./hack/for-each-module.sh "make build" "./plugin/*" 16
|
||||
|
||||
.PHONY: test-unit-kustomize-plugins
|
||||
test-unit-kustomize-plugins:
|
||||
@@ -153,7 +164,7 @@ functions-examples-all:
|
||||
done
|
||||
|
||||
test-go-mod:
|
||||
./hack/for-each-module.sh "\$$KUSTOMIZE_ROOT/hack/with-unpinned-kust-dev.sh 'go mod tidy -v'"
|
||||
./hack/for-each-module.sh "go mod tidy -v"
|
||||
|
||||
.PHONY:
|
||||
verify-kustomize-e2e: $(MYGOBIN)/mdrip $(MYGOBIN)/kind
|
||||
@@ -170,10 +181,15 @@ test-examples-kustomize-against-HEAD: $(MYGOBIN)/kustomize $(MYGOBIN)/mdrip
|
||||
./hack/testExamplesAgainstKustomize.sh HEAD
|
||||
|
||||
.PHONY:
|
||||
test-examples-kustomize-against-v4-release: $(MYGOBIN)/mdrip
|
||||
./hack/testExamplesAgainstKustomize.sh v4@$(LATEST_V4_RELEASE)
|
||||
|
||||
test-examples-kustomize-against-latest-release: $(MYGOBIN)/mdrip
|
||||
./hack/testExamplesAgainstKustomize.sh v5@$(LATEST_RELEASE)
|
||||
|
||||
# Pushes dependencies in the go.work file back to go.mod files of each workspace module.
|
||||
.PHONY: workspace-sync
|
||||
workspace-sync:
|
||||
go work sync
|
||||
./hack/doGoMod.sh tidy
|
||||
|
||||
# --- Cleanup targets ---
|
||||
.PHONY: clean
|
||||
clean: clean-kustomize-external-go-plugin uninstall-tools
|
||||
|
||||
@@ -14,6 +14,7 @@ include $(KUSTOMIZE_ROOT)/Makefile-tools.mk
|
||||
.PHONY: lint test fix fmt tidy vet build
|
||||
|
||||
lint: $(MYGOBIN)/golangci-lint
|
||||
$(MYGOBIN)/golangci-lint cache clean # Workaround for https://github.com/golangci/golangci-lint/issues/3228
|
||||
$(MYGOBIN)/golangci-lint \
|
||||
-c $$KUSTOMIZE_ROOT/.golangci.yml \
|
||||
--path-prefix $(shell pwd | sed -E 's|(.*\/kustomize)/(.*)|\2|') \
|
||||
|
||||
@@ -89,9 +89,27 @@ $(pGen)/%.go: $(MYGOBIN)/pluginator $(MYGOBIN)/goimports
|
||||
$(MYGOBIN)/goimports -w $*.go \
|
||||
)
|
||||
|
||||
# Target is for debugging.
|
||||
# Generate builtin plugins
|
||||
.PHONY: generate-kustomize-builtin-plugins
|
||||
generate-kustomize-builtin-plugins: $(builtinplugins)
|
||||
generate-kustomize-builtin-plugins: $(builtplugins)
|
||||
for plugin in $(abspath $(wildcard $(pSrc)/*)); do \
|
||||
echo "generating $${plugin} ..."; \
|
||||
set -e; \
|
||||
cd $${plugin}; \
|
||||
go generate pluginator .; \
|
||||
done
|
||||
|
||||
# Check for diff by comparing current revision of generated plugins on HEAD and newly generated plugins on local branch,
|
||||
# If diff is found, throw error code 1
|
||||
.PHONY: builtin-plugins-diff
|
||||
builtin-plugins-diff: $(builtplugins)
|
||||
for file in $(abspath $(builtinplugins)); do \
|
||||
echo "Checking for diff... $${file}" ; \
|
||||
set -e ; \
|
||||
if [ "`git diff $${file} | wc -c`" -gt 0 ]; then\
|
||||
echo "Error(1): diff found on $${file}"; exit 1; \
|
||||
fi \
|
||||
done
|
||||
|
||||
.PHONY: build-kustomize-external-go-plugin
|
||||
build-kustomize-external-go-plugin:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Copyright 2022 The Kubernetes Authors.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
GOLANGCI_LINT_VERSION=v1.50.1
|
||||
GOLANGCI_LINT_VERSION=v1.51.2
|
||||
|
||||
MYGOBIN = $(shell go env GOBIN)
|
||||
ifeq ($(MYGOBIN),)
|
||||
|
||||
1
OWNERS
1
OWNERS
@@ -1,6 +1,5 @@
|
||||
# See https://github.com/kubernetes/community/blob/master/community-membership.md
|
||||
approvers:
|
||||
- kustomize-approvers
|
||||
|
||||
reviewers:
|
||||
- kustomize-reviewers
|
||||
|
||||
@@ -7,25 +7,20 @@ aliases:
|
||||
kustomize-approvers:
|
||||
- knverey
|
||||
- natasha41575
|
||||
- annasong20
|
||||
- koba1t
|
||||
kustomize-reviewers:
|
||||
- knverey
|
||||
- natasha41575
|
||||
- yuwenma
|
||||
- annasong20
|
||||
- koba1t
|
||||
|
||||
kyaml-approvers:
|
||||
- mengqiy
|
||||
- mortent
|
||||
- phanimarupaka
|
||||
kyaml-reviewers:
|
||||
- mengqiy
|
||||
- mortent
|
||||
- phanimarupaka
|
||||
|
||||
emeritus-approvers:
|
||||
- liujingfang1
|
||||
- Shell32-Natsu
|
||||
- justinsb
|
||||
- monopole
|
||||
- pwittrock
|
||||
# emeritus:
|
||||
# - liujingfang1
|
||||
# - Shell32-Natsu
|
||||
# - justinsb
|
||||
# - monopole
|
||||
# - pwittrock
|
||||
# - mengqiy
|
||||
# - mortent
|
||||
# - phanimarupaka
|
||||
|
||||
92
README.md
92
README.md
@@ -20,6 +20,14 @@ This tool is sponsored by [sig-cli] ([KEP]).
|
||||
|
||||
## kubectl integration
|
||||
|
||||
To find the kustomize version embedded in recent versions of kubectl, run `kubectl version`:
|
||||
|
||||
```sh
|
||||
> kubectl version --short --client
|
||||
Client Version: v1.26.0
|
||||
Kustomize Version: v4.5.7
|
||||
```
|
||||
|
||||
The kustomize build flow at [v2.0.3] was added
|
||||
to [kubectl v1.14][kubectl announcement]. The kustomize
|
||||
flow in kubectl remained frozen at v2.0.3 until kubectl v1.21,
|
||||
@@ -28,11 +36,16 @@ be updated on a regular basis going forward, and such updates
|
||||
will be reflected in the Kubernetes release notes.
|
||||
|
||||
| Kubectl version | Kustomize version |
|
||||
| --- | --- |
|
||||
| < v1.14 | n/a |
|
||||
| v1.14-v1.20 | v2.0.3 |
|
||||
| v1.21 | v4.0.5 |
|
||||
| v1.22 | v4.2.0 |
|
||||
| --------------- | ----------------- |
|
||||
| < v1.14 | n/a |
|
||||
| v1.14-v1.20 | v2.0.3 |
|
||||
| v1.21 | v4.0.5 |
|
||||
| v1.22 | v4.2.0 |
|
||||
| v1.23 | v4.4.1 |
|
||||
| v1.24 | v4.5.4 |
|
||||
| v1.25 | v4.5.7 |
|
||||
| v1.26 | v4.5.7 |
|
||||
| v1.27 | v5.0.1 |
|
||||
|
||||
[v2.0.3]: https://github.com/kubernetes-sigs/kustomize/releases/tag/v2.0.3
|
||||
[#2506]: https://github.com/kubernetes-sigs/kustomize/issues/2506
|
||||
@@ -55,7 +68,37 @@ This file should declare those resources, and any
|
||||
customization to apply to them, e.g. _add a common
|
||||
label_.
|
||||
|
||||
![base image][imageBase]
|
||||
```
|
||||
|
||||
base: kustomization + resources
|
||||
|
||||
kustomization.yaml deployment.yaml service.yaml
|
||||
+---------------------------------------------+ +-------------------------------------------------------+ +-----------------------------------+
|
||||
| apiVersion: kustomize.config.k8s.io/v1beta1 | | apiVersion: apps/v1 | | apiVersion: v1 |
|
||||
| kind: Kustomization | | kind: Deployment | | kind: Service |
|
||||
|.commonLabels: | | metadata: | | metadata: |
|
||||
| app: myapp | | name: myapp | | name: myapp |
|
||||
| resources: | | spec: | | spec: |
|
||||
| - deployment.yaml | | selector: | | selector: |
|
||||
| - service.yaml | | matchLabels: | | app: myapp |
|
||||
| configMapGenerator: | | app: myapp | | ports: |
|
||||
| - name: myapp-map | | template: | | - port: 6060 |
|
||||
| literals: | | metadata: | | targetPort: 6060 |
|
||||
| - KEY=value | | labels: | +-----------------------------------+
|
||||
+---------------------------------------------+ | app: myapp |
|
||||
| spec: |
|
||||
| containers: |
|
||||
| - name: myapp |
|
||||
| image: myapp |
|
||||
| resources: |
|
||||
| limits: |
|
||||
| memory: "128Mi" |
|
||||
| cpu: "500m" |
|
||||
| ports: |
|
||||
| - containerPort: 6060 |
|
||||
+-------------------------------------------------------+
|
||||
|
||||
```
|
||||
|
||||
File structure:
|
||||
|
||||
@@ -91,20 +134,41 @@ Manage traditional [variants] of a configuration - like
|
||||
_development_, _staging_ and _production_ - using
|
||||
[overlays] that modify a common [base].
|
||||
|
||||
![overlay image][imageOverlay]
|
||||
```
|
||||
|
||||
overlay: kustomization + patches
|
||||
|
||||
kustomization.yaml replica_count.yaml cpu_count.yaml
|
||||
+-----------------------------------------------+ +-------------------------------+ +------------------------------------------+
|
||||
| apiVersion: kustomize.config.k8s.io/v1beta1 | | apiVersion: apps/v1 | | apiVersion: apps/v1 |
|
||||
| kind: Kustomization | | kind: Deployment | | kind: Deployment |
|
||||
| commonLabels: | | metadata: | | metadata: |
|
||||
| variant: prod | | name: myapp | | name: myapp |
|
||||
| resources: | | spec: | | spec: |
|
||||
| - ../../base | | replicas: 80 | | template: |
|
||||
| patches: | +-------------------------------+ | spec: |
|
||||
| - path: replica_count.yaml | | containers: |
|
||||
| - path: cpu_count.yaml | | - name: myapp |
|
||||
+-----------------------------------------------+ | resources: |
|
||||
| limits: |
|
||||
| memory: "128Mi" |
|
||||
| cpu: "7000m" |
|
||||
+------------------------------------------+
|
||||
```
|
||||
|
||||
|
||||
File structure:
|
||||
> ```
|
||||
> ~/someApp
|
||||
> ├── base
|
||||
> │ ├── deployment.yaml
|
||||
> │ ├── kustomization.yaml
|
||||
> │ └── service.yaml
|
||||
> │ ├── deployment.yaml
|
||||
> │ ├── kustomization.yaml
|
||||
> │ └── service.yaml
|
||||
> └── overlays
|
||||
> ├── development
|
||||
> │ ├── cpu_count.yaml
|
||||
> │ ├── kustomization.yaml
|
||||
> │ └── replica_count.yaml
|
||||
> │ ├── cpu_count.yaml
|
||||
> │ ├── kustomization.yaml
|
||||
> │ └── replica_count.yaml
|
||||
> └── production
|
||||
> ├── cpu_count.yaml
|
||||
> ├── kustomization.yaml
|
||||
@@ -158,8 +222,6 @@ is governed by the [Kubernetes Code of Conduct].
|
||||
[applied]: https://kubectl.docs.kubernetes.io/references/kustomize/glossary/#apply
|
||||
[base]: https://kubectl.docs.kubernetes.io/references/kustomize/glossary/#base
|
||||
[declarative configuration]: https://kubectl.docs.kubernetes.io/references/kustomize/glossary/#declarative-application-management
|
||||
[imageBase]: images/base.jpg
|
||||
[imageOverlay]: images/overlay.jpg
|
||||
[kubectl announcement]: https://kubernetes.io/blog/2019/03/25/kubernetes-1-14-release-announcement
|
||||
[kubernetes documentation]: https://kubernetes.io/docs/tasks/manage-kubernetes-objects/kustomization/
|
||||
[kubernetes style]: https://kubectl.docs.kubernetes.io/references/kustomize/glossary/#kubernetes-style-object
|
||||
|
||||
@@ -6,7 +6,7 @@ package imagetag
|
||||
import (
|
||||
"sigs.k8s.io/kustomize/api/filters/filtersutil"
|
||||
|
||||
"sigs.k8s.io/kustomize/api/image"
|
||||
"sigs.k8s.io/kustomize/api/internal/image"
|
||||
"sigs.k8s.io/kustomize/api/types"
|
||||
"sigs.k8s.io/kustomize/kyaml/yaml"
|
||||
)
|
||||
|
||||
@@ -56,9 +56,11 @@ func (ns Filter) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) {
|
||||
|
||||
// Run runs the filter on a single node rather than a slice
|
||||
func (ns Filter) run(node *yaml.RNode) (*yaml.RNode, error) {
|
||||
// Special handling for metadata.namespace -- :(
|
||||
// Special handling for metadata.namespace and metadata.name -- :(
|
||||
// never let SetEntry handle metadata.namespace--it will incorrectly include cluster-scoped resources
|
||||
ns.FsSlice = ns.removeMetaNamespaceFieldSpecs(ns.FsSlice)
|
||||
// only update metadata.name if api version is expected one--so-as it leaves other resources of kind namespace alone
|
||||
apiVersion := node.GetApiVersion()
|
||||
ns.FsSlice = ns.removeUnneededMetaFieldSpecs(apiVersion, ns.FsSlice)
|
||||
gvk := resid.GvkFromNode(node)
|
||||
if err := ns.metaNamespaceHack(node, gvk); err != nil {
|
||||
return nil, err
|
||||
@@ -186,12 +188,15 @@ func (ns Filter) removeRoleBindingSubjectFieldSpecs(fs types.FsSlice) types.FsSl
|
||||
return val
|
||||
}
|
||||
|
||||
func (ns Filter) removeMetaNamespaceFieldSpecs(fs types.FsSlice) types.FsSlice {
|
||||
func (ns Filter) removeUnneededMetaFieldSpecs(apiVersion string, fs types.FsSlice) types.FsSlice {
|
||||
var val types.FsSlice
|
||||
for i := range fs {
|
||||
if fs[i].Path == types.MetadataNamespacePath {
|
||||
continue
|
||||
}
|
||||
if apiVersion != types.MetadataNamespaceApiVersion && fs[i].Path == types.MetadataNamePath {
|
||||
continue
|
||||
}
|
||||
val = append(val, fs[i])
|
||||
}
|
||||
return val
|
||||
|
||||
@@ -6,7 +6,7 @@ package patchjson6902
|
||||
import (
|
||||
"strings"
|
||||
|
||||
jsonpatch "github.com/evanphx/json-patch"
|
||||
jsonpatch "gopkg.in/evanphx/json-patch.v5"
|
||||
"sigs.k8s.io/kustomize/kyaml/kio"
|
||||
"sigs.k8s.io/kustomize/kyaml/yaml"
|
||||
k8syaml "sigs.k8s.io/yaml"
|
||||
|
||||
@@ -776,6 +776,133 @@ spec:
|
||||
autoscaling: true
|
||||
deepgram-api:
|
||||
some: value
|
||||
`,
|
||||
},
|
||||
|
||||
// Issue #4928
|
||||
"support numeric keys": {
|
||||
input: `
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: blabla
|
||||
namespace: blabla-ns
|
||||
data:
|
||||
"6443": "foobar"
|
||||
`,
|
||||
patch: yaml.MustParse(`
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: blabla
|
||||
namespace: blabla-ns
|
||||
data:
|
||||
"6443": "barfoo"
|
||||
"9110": "foo-foo"
|
||||
`),
|
||||
expected: `
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: blabla
|
||||
namespace: blabla-ns
|
||||
data:
|
||||
"6443": "barfoo"
|
||||
"9110": "foo-foo"
|
||||
`,
|
||||
},
|
||||
|
||||
"honor different key style one": {
|
||||
input: `
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: blabla
|
||||
namespace: blabla-ns
|
||||
data:
|
||||
'6443': "foobar"
|
||||
`,
|
||||
patch: yaml.MustParse(`
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: blabla
|
||||
namespace: blabla-ns
|
||||
data:
|
||||
"6443": "barfoo"
|
||||
9110: "foo-foo"
|
||||
`),
|
||||
expected: `
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: blabla
|
||||
namespace: blabla-ns
|
||||
data:
|
||||
'6443': "barfoo"
|
||||
9110: "foo-foo"
|
||||
`,
|
||||
},
|
||||
|
||||
"honor different key style two": {
|
||||
input: `
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: blabla
|
||||
namespace: blabla-ns
|
||||
data:
|
||||
"6443": "foobar"
|
||||
`,
|
||||
patch: yaml.MustParse(`
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: blabla
|
||||
namespace: blabla-ns
|
||||
data:
|
||||
"6443": "barfoo"
|
||||
'9110': "foo-foo"
|
||||
`),
|
||||
expected: `
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: blabla
|
||||
namespace: blabla-ns
|
||||
data:
|
||||
"6443": "barfoo"
|
||||
'9110': "foo-foo"
|
||||
`,
|
||||
},
|
||||
|
||||
"different key types": {
|
||||
input: `
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: blabla
|
||||
namespace: blabla-ns
|
||||
data:
|
||||
"6443": "key-string-double-quoted"
|
||||
`,
|
||||
patch: yaml.MustParse(`
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: blabla
|
||||
namespace: blabla-ns
|
||||
data:
|
||||
6443: "key-int"
|
||||
`),
|
||||
expected: `
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: blabla
|
||||
namespace: blabla-ns
|
||||
data:
|
||||
"6443": "key-int"
|
||||
`,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -126,8 +126,8 @@ func applyReplacement(nodes []*yaml.RNode, value *yaml.RNode, targetSelectors []
|
||||
}
|
||||
|
||||
// filter targets by matching resource IDs
|
||||
for i, id := range ids {
|
||||
if id.IsSelectedBy(selector.Select.ResId) && !rejectId(selector.Reject, &ids[i]) {
|
||||
for _, id := range ids {
|
||||
if id.IsSelectedBy(selector.Select.ResId) && !containsRejectId(selector.Reject, ids) {
|
||||
err := copyValueToTarget(possibleTarget, value, selector)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -168,10 +168,15 @@ func matchesAnnoAndLabelSelector(n *yaml.RNode, selector *types.Selector) (bool,
|
||||
return annoMatch && labelMatch, nil
|
||||
}
|
||||
|
||||
func rejectId(rejects []*types.Selector, id *resid.ResId) bool {
|
||||
func containsRejectId(rejects []*types.Selector, ids []resid.ResId) bool {
|
||||
for _, r := range rejects {
|
||||
if !r.ResId.IsEmpty() && id.IsSelectedBy(r.ResId) {
|
||||
return true
|
||||
if r.ResId.IsEmpty() {
|
||||
continue
|
||||
}
|
||||
for _, id := range ids {
|
||||
if id.IsSelectedBy(r.ResId) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
|
||||
26
api/go.mod
26
api/go.mod
@@ -1,37 +1,37 @@
|
||||
module sigs.k8s.io/kustomize/api
|
||||
|
||||
go 1.19
|
||||
go 1.20
|
||||
|
||||
require (
|
||||
github.com/evanphx/json-patch v4.11.0+incompatible
|
||||
github.com/go-errors/errors v1.4.2
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
|
||||
github.com/imdario/mergo v0.3.6
|
||||
github.com/imdario/mergo v0.3.13
|
||||
github.com/stretchr/testify v1.8.1
|
||||
gopkg.in/evanphx/json-patch.v5 v5.6.0
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
k8s.io/kube-openapi v0.0.0-20230109183929-3758b55a6596
|
||||
sigs.k8s.io/kustomize/kyaml v0.14.0
|
||||
k8s.io/kube-openapi v0.0.0-20230601164746-7562a1006961
|
||||
sigs.k8s.io/kustomize/kyaml v0.15.0
|
||||
sigs.k8s.io/yaml v1.3.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.19.6 // indirect
|
||||
github.com/go-openapi/jsonreference v0.20.1 // indirect
|
||||
github.com/go-openapi/jsonreference v0.20.2 // indirect
|
||||
github.com/go-openapi/swag v0.22.3 // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/google/gnostic v0.5.7-v3refs // indirect
|
||||
github.com/google/go-cmp v0.5.5 // indirect
|
||||
github.com/google/gofuzz v1.1.0 // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/google/gnostic-models v0.6.8 // indirect
|
||||
github.com/google/go-cmp v0.5.9 // indirect
|
||||
github.com/google/gofuzz v1.2.0 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/sergi/go-diff v1.1.0 // indirect
|
||||
github.com/xlab/treeprint v1.1.0 // indirect
|
||||
github.com/xlab/treeprint v1.2.0 // indirect
|
||||
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect
|
||||
golang.org/x/sys v0.3.0 // indirect
|
||||
google.golang.org/protobuf v1.28.0 // indirect
|
||||
golang.org/x/sys v0.12.0 // indirect
|
||||
google.golang.org/protobuf v1.30.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
119
api/go.sum
119
api/go.sum
@@ -1,60 +1,37 @@
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/evanphx/json-patch v4.11.0+incompatible h1:glyUF9yIYtMHzn8xaKw5rMhdWcwsYV8dZHIq5567/xs=
|
||||
github.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||
github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA=
|
||||
github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og=
|
||||
github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE=
|
||||
github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=
|
||||
github.com/go-openapi/jsonreference v0.20.1 h1:FBLnyygC4/IZZr893oiomc9XaghoveYTrLC1F86HID8=
|
||||
github.com/go-openapi/jsonreference v0.20.1/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=
|
||||
github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE=
|
||||
github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=
|
||||
github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g=
|
||||
github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
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/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.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.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
||||
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
||||
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I=
|
||||
github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
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/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
|
||||
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
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/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28=
|
||||
github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||
github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk=
|
||||
github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg=
|
||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
@@ -67,89 +44,49 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
|
||||
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
|
||||
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||
github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/xlab/treeprint v1.1.0 h1:G/1DjNkPpfZCFt9CSh6b5/nY4VimlbHF3Rh4obvtzDk=
|
||||
github.com/xlab/treeprint v1.1.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0=
|
||||
github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ=
|
||||
github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0=
|
||||
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 h1:+FNtrFTmVw0YZGpBGX56XDee331t6JAXeK2bcyhLOOc=
|
||||
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20191002063906-3421d5a6bb1c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ=
|
||||
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o=
|
||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/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=
|
||||
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
|
||||
google.golang.org/protobuf v1.30.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 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/evanphx/json-patch.v5 v5.6.0 h1:BMT6KIwBD9CaU91PJCZIe46bDmBWa9ynTQgJIOpfQBk=
|
||||
gopkg.in/evanphx/json-patch.v5 v5.6.0/go.mod h1:/kvTRh1TVm5wuM6OkHxqXtE/1nUZZpihg29RtuIyfvk=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
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.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
k8s.io/kube-openapi v0.0.0-20230109183929-3758b55a6596 h1:8cNCQs+WqqnSpZ7y0LMQPKD+RZUHU17VqLPMW3qxnxc=
|
||||
k8s.io/kube-openapi v0.0.0-20230109183929-3758b55a6596/go.mod h1:/BYxry62FuDzmI+i9B+X2pqfySRmSOW2ARmj5Zbqhj0=
|
||||
sigs.k8s.io/kustomize/kyaml v0.14.0 h1:uzH0MzMtYypHW09LbMDk8k/lT/LSsUuCoZIuEGhIBNE=
|
||||
sigs.k8s.io/kustomize/kyaml v0.14.0/go.mod h1:AN1/IpawKilWD7V+YvQwRGUvuUOOWpjsHu6uHwonSF4=
|
||||
k8s.io/kube-openapi v0.0.0-20230601164746-7562a1006961 h1:pqRVJGQJz6oeZby8qmPKXYIBjyrcv7EHCe/33UkZMYA=
|
||||
k8s.io/kube-openapi v0.0.0-20230601164746-7562a1006961/go.mod h1:l8HTwL5fqnlns4jOveW1L75eo7R9KFHxiE0bsPGy428=
|
||||
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
|
||||
sigs.k8s.io/kustomize/kyaml v0.15.0 h1:ynlLMAxDhrY9otSg5GYE2TcIz31XkGZ2Pkj7SdolD84=
|
||||
sigs.k8s.io/kustomize/kyaml v0.15.0/go.mod h1:+uMkBahdU1KNOj78Uta4rrXH+iH7wvg+nW7+GULvREA=
|
||||
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
|
||||
sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=
|
||||
|
||||
@@ -9,8 +9,8 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
. "sigs.k8s.io/kustomize/api/internal/accumulator"
|
||||
"sigs.k8s.io/kustomize/api/internal/loader"
|
||||
"sigs.k8s.io/kustomize/api/internal/plugins/builtinconfig"
|
||||
"sigs.k8s.io/kustomize/api/loader"
|
||||
"sigs.k8s.io/kustomize/api/types"
|
||||
"sigs.k8s.io/kustomize/kyaml/filesys"
|
||||
"sigs.k8s.io/kustomize/kyaml/resid"
|
||||
|
||||
@@ -170,9 +170,10 @@ func (ra *ResAccumulator) FixBackReferences() (err error) {
|
||||
|
||||
// Intersection drops the resources which "other" does not have.
|
||||
func (ra *ResAccumulator) Intersection(other resmap.ResMap) error {
|
||||
otherIds := other.AllIds()
|
||||
for _, curId := range ra.resMap.AllIds() {
|
||||
toDelete := true
|
||||
for _, otherId := range other.AllIds() {
|
||||
for _, otherId := range otherIds {
|
||||
if otherId == curId {
|
||||
toDelete = false
|
||||
break
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Code generated by pluginator on AnnotationsTransformer; DO NOT EDIT.
|
||||
// pluginator {unknown 1970-01-01T00:00:00Z }
|
||||
// pluginator {(devel) unknown }
|
||||
|
||||
package builtins
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Code generated by pluginator on ConfigMapGenerator; DO NOT EDIT.
|
||||
// pluginator {unknown 1970-01-01T00:00:00Z }
|
||||
// pluginator {(devel) unknown }
|
||||
|
||||
package builtins
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Code generated by pluginator on HashTransformer; DO NOT EDIT.
|
||||
// pluginator {unknown 1970-01-01T00:00:00Z }
|
||||
// pluginator {(devel) unknown }
|
||||
|
||||
package builtins
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Code generated by pluginator on HelmChartInflationGenerator; DO NOT EDIT.
|
||||
// pluginator {unknown 1970-01-01T00:00:00Z }
|
||||
// pluginator {(devel) unknown }
|
||||
|
||||
package builtins
|
||||
|
||||
@@ -155,8 +155,8 @@ func (p *HelmChartInflationGeneratorPlugin) runHelmCommand(
|
||||
helm := p.h.GeneralConfig().HelmConfig.Command
|
||||
err = errors.WrapPrefixf(
|
||||
fmt.Errorf(
|
||||
"unable to run: '%s %s' with env=%s (is '%s' installed?)",
|
||||
helm, strings.Join(args, " "), env, helm),
|
||||
"unable to run: '%s %s' with env=%s (is '%s' installed?): %w",
|
||||
helm, strings.Join(args, " "), env, helm, err),
|
||||
stderr.String(),
|
||||
)
|
||||
}
|
||||
@@ -262,15 +262,18 @@ func (p *HelmChartInflationGeneratorPlugin) Generate() (rm resmap.ResMap, err er
|
||||
// helm may produce messages to stdout before it
|
||||
r := &kio.ByteReader{Reader: bytes.NewBufferString(string(stdout)), OmitReaderAnnotations: true}
|
||||
nodes, err := r.Read()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error reading helm output: %w", err)
|
||||
}
|
||||
|
||||
if len(nodes) != 0 {
|
||||
rm, err = p.h.ResmapFactory().NewResMapFromRNodeSlice(nodes)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not parse rnode slice into resource map: %w\n", err)
|
||||
return nil, fmt.Errorf("could not parse rnode slice into resource map: %w", err)
|
||||
}
|
||||
return rm, nil
|
||||
}
|
||||
return nil, fmt.Errorf("could not parse bytes into resource map: %w\n", resMapErr)
|
||||
return nil, fmt.Errorf("could not parse bytes into resource map: %w", resMapErr)
|
||||
}
|
||||
|
||||
func (p *HelmChartInflationGeneratorPlugin) pullCommand() []string {
|
||||
@@ -278,8 +281,18 @@ func (p *HelmChartInflationGeneratorPlugin) pullCommand() []string {
|
||||
"pull",
|
||||
"--untar",
|
||||
"--untardir", p.absChartHome(),
|
||||
"--repo", p.Repo,
|
||||
p.Name}
|
||||
}
|
||||
|
||||
switch {
|
||||
case strings.HasPrefix(p.Repo, "oci://"):
|
||||
args = append(args, strings.TrimSuffix(p.Repo, "/")+"/"+p.Name)
|
||||
case p.Repo != "":
|
||||
args = append(args, "--repo", p.Repo)
|
||||
fallthrough
|
||||
default:
|
||||
args = append(args, p.Name)
|
||||
}
|
||||
|
||||
if p.Version != "" {
|
||||
args = append(args, "--version", p.Version)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Code generated by pluginator on IAMPolicyGenerator; DO NOT EDIT.
|
||||
// pluginator {unknown 1970-01-01T00:00:00Z }
|
||||
// pluginator {(devel) unknown }
|
||||
|
||||
package builtins
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Code generated by pluginator on ImageTagTransformer; DO NOT EDIT.
|
||||
// pluginator {unknown 1970-01-01T00:00:00Z }
|
||||
// pluginator {(devel) unknown }
|
||||
|
||||
package builtins
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Code generated by pluginator on LabelTransformer; DO NOT EDIT.
|
||||
// pluginator {unknown 1970-01-01T00:00:00Z }
|
||||
// pluginator {(devel) unknown }
|
||||
|
||||
package builtins
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Code generated by pluginator on NamespaceTransformer; DO NOT EDIT.
|
||||
// pluginator {unknown 1970-01-01T00:00:00Z }
|
||||
// pluginator {(devel) unknown }
|
||||
|
||||
package builtins
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
// Code generated by pluginator on PatchJson6902Transformer; DO NOT EDIT.
|
||||
// pluginator {unknown 1970-01-01T00:00:00Z }
|
||||
// pluginator {(devel) unknown }
|
||||
|
||||
package builtins
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
jsonpatch "github.com/evanphx/json-patch"
|
||||
jsonpatch "gopkg.in/evanphx/json-patch.v5"
|
||||
"sigs.k8s.io/kustomize/api/filters/patchjson6902"
|
||||
"sigs.k8s.io/kustomize/api/ifc"
|
||||
"sigs.k8s.io/kustomize/api/resmap"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Code generated by pluginator on PatchStrategicMergeTransformer; DO NOT EDIT.
|
||||
// pluginator {unknown 1970-01-01T00:00:00Z }
|
||||
// pluginator {(devel) unknown }
|
||||
|
||||
package builtins
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Code generated by pluginator on PatchTransformer; DO NOT EDIT.
|
||||
// pluginator {unknown 1970-01-01T00:00:00Z }
|
||||
// pluginator {(devel) unknown }
|
||||
|
||||
package builtins
|
||||
|
||||
@@ -7,104 +7,123 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
jsonpatch "github.com/evanphx/json-patch"
|
||||
jsonpatch "gopkg.in/evanphx/json-patch.v5"
|
||||
"sigs.k8s.io/kustomize/api/filters/patchjson6902"
|
||||
"sigs.k8s.io/kustomize/api/resmap"
|
||||
"sigs.k8s.io/kustomize/api/resource"
|
||||
"sigs.k8s.io/kustomize/api/types"
|
||||
"sigs.k8s.io/kustomize/kyaml/errors"
|
||||
"sigs.k8s.io/kustomize/kyaml/kio/kioutil"
|
||||
"sigs.k8s.io/yaml"
|
||||
)
|
||||
|
||||
type PatchTransformerPlugin struct {
|
||||
loadedPatch *resource.Resource
|
||||
decodedPatch jsonpatch.Patch
|
||||
Path string `json:"path,omitempty" yaml:"path,omitempty"`
|
||||
Patch string `json:"patch,omitempty" yaml:"patch,omitempty"`
|
||||
Target *types.Selector `json:"target,omitempty" yaml:"target,omitempty"`
|
||||
Options map[string]bool `json:"options,omitempty" yaml:"options,omitempty"`
|
||||
smPatches []*resource.Resource // strategic-merge patches
|
||||
jsonPatches jsonpatch.Patch // json6902 patch
|
||||
// patchText is pure patch text created by Path or Patch
|
||||
patchText string
|
||||
// patchSource is patch source message
|
||||
patchSource string
|
||||
Path string `json:"path,omitempty" yaml:"path,omitempty"`
|
||||
Patch string `json:"patch,omitempty" yaml:"patch,omitempty"`
|
||||
Target *types.Selector `json:"target,omitempty" yaml:"target,omitempty"`
|
||||
Options map[string]bool `json:"options,omitempty" yaml:"options,omitempty"`
|
||||
}
|
||||
|
||||
func (p *PatchTransformerPlugin) Config(
|
||||
h *resmap.PluginHelpers, c []byte) error {
|
||||
err := yaml.Unmarshal(c, p)
|
||||
if err != nil {
|
||||
func (p *PatchTransformerPlugin) Config(h *resmap.PluginHelpers, c []byte) error {
|
||||
if err := yaml.Unmarshal(c, p); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
p.Patch = strings.TrimSpace(p.Patch)
|
||||
if p.Patch == "" && p.Path == "" {
|
||||
return fmt.Errorf(
|
||||
"must specify one of patch and path in\n%s", string(c))
|
||||
}
|
||||
if p.Patch != "" && p.Path != "" {
|
||||
return fmt.Errorf(
|
||||
"patch and path can't be set at the same time\n%s", string(c))
|
||||
}
|
||||
if p.Path != "" {
|
||||
loaded, loadErr := h.Loader().Load(p.Path)
|
||||
if loadErr != nil {
|
||||
return loadErr
|
||||
switch {
|
||||
case p.Patch == "" && p.Path == "":
|
||||
return fmt.Errorf("must specify one of patch and path in\n%s", string(c))
|
||||
case p.Patch != "" && p.Path != "":
|
||||
return fmt.Errorf("patch and path can't be set at the same time\n%s", string(c))
|
||||
case p.Patch != "":
|
||||
p.patchText = p.Patch
|
||||
p.patchSource = fmt.Sprintf("[patch: %q]", p.patchText)
|
||||
case p.Path != "":
|
||||
loaded, err := h.Loader().Load(p.Path)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get the patch file from path(%s): %w", p.Path, err)
|
||||
}
|
||||
p.Patch = string(loaded)
|
||||
p.patchText = string(loaded)
|
||||
p.patchSource = fmt.Sprintf("[path: %q]", p.Path)
|
||||
}
|
||||
|
||||
patchSM, errSM := h.ResmapFactory().RF().FromBytes([]byte(p.Patch))
|
||||
patchJson, errJson := jsonPatchFromBytes([]byte(p.Patch))
|
||||
patchesSM, errSM := h.ResmapFactory().RF().SliceFromBytes([]byte(p.patchText))
|
||||
patchesJson, errJson := jsonPatchFromBytes([]byte(p.patchText))
|
||||
|
||||
if (errSM == nil && errJson == nil) ||
|
||||
(patchSM != nil && patchJson != nil) {
|
||||
(patchesSM != nil && patchesJson != nil) {
|
||||
return fmt.Errorf(
|
||||
"illegally qualifies as both an SM and JSON patch: [%v]",
|
||||
p.Patch)
|
||||
"illegally qualifies as both an SM and JSON patch: %s",
|
||||
p.patchSource)
|
||||
}
|
||||
if errSM != nil && errJson != nil {
|
||||
return fmt.Errorf(
|
||||
"unable to parse SM or JSON patch from [%v]", p.Patch)
|
||||
"unable to parse SM or JSON patch from %s", p.patchSource)
|
||||
}
|
||||
if errSM == nil {
|
||||
p.loadedPatch = patchSM
|
||||
if p.Options["allowNameChange"] {
|
||||
p.loadedPatch.AllowNameChange()
|
||||
}
|
||||
if p.Options["allowKindChange"] {
|
||||
p.loadedPatch.AllowKindChange()
|
||||
p.smPatches = patchesSM
|
||||
for _, loadedPatch := range p.smPatches {
|
||||
if p.Options["allowNameChange"] {
|
||||
loadedPatch.AllowNameChange()
|
||||
}
|
||||
if p.Options["allowKindChange"] {
|
||||
loadedPatch.AllowKindChange()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
p.decodedPatch = patchJson
|
||||
p.jsonPatches = patchesJson
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *PatchTransformerPlugin) Transform(m resmap.ResMap) error {
|
||||
if p.loadedPatch == nil {
|
||||
return p.transformJson6902(m, p.decodedPatch)
|
||||
if p.smPatches != nil {
|
||||
return p.transformStrategicMerge(m)
|
||||
}
|
||||
// The patch was a strategic merge patch
|
||||
return p.transformStrategicMerge(m, p.loadedPatch)
|
||||
return p.transformJson6902(m)
|
||||
}
|
||||
|
||||
// transformStrategicMerge applies the provided strategic merge patch
|
||||
// to all the resources in the ResMap that match either the Target or
|
||||
// the identifier of the patch.
|
||||
func (p *PatchTransformerPlugin) transformStrategicMerge(m resmap.ResMap, patch *resource.Resource) error {
|
||||
if p.Target == nil {
|
||||
// transformStrategicMerge applies each loaded strategic merge patch
|
||||
// to the resource in the ResMap that matches the identifier of the patch.
|
||||
// If only one patch is specified, the Target can be used instead.
|
||||
func (p *PatchTransformerPlugin) transformStrategicMerge(m resmap.ResMap) error {
|
||||
if p.Target != nil {
|
||||
if len(p.smPatches) > 1 {
|
||||
// detail: https://github.com/kubernetes-sigs/kustomize/issues/5049#issuecomment-1440604403
|
||||
return fmt.Errorf("Multiple Strategic-Merge Patches in one `patches` entry is not allowed to set `patches.target` field: %s", p.patchSource)
|
||||
}
|
||||
|
||||
// single patch
|
||||
patch := p.smPatches[0]
|
||||
selected, err := m.Select(*p.Target)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to find patch target %q in `resources`: %w", p.Target, err)
|
||||
}
|
||||
return errors.Wrap(m.ApplySmPatch(resource.MakeIdSet(selected), patch))
|
||||
}
|
||||
|
||||
for _, patch := range p.smPatches {
|
||||
target, err := m.GetById(patch.OrgId())
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("no resource matches strategic merge patch %q: %w", patch.OrgId(), err)
|
||||
}
|
||||
if err := target.ApplySmPatch(patch); err != nil {
|
||||
return errors.Wrap(err)
|
||||
}
|
||||
return target.ApplySmPatch(patch)
|
||||
}
|
||||
selected, err := m.Select(*p.Target)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return m.ApplySmPatch(resource.MakeIdSet(selected), patch)
|
||||
return nil
|
||||
}
|
||||
|
||||
// transformJson6902 applies the provided json6902 patch
|
||||
// to all the resources in the ResMap that match the Target.
|
||||
func (p *PatchTransformerPlugin) transformJson6902(m resmap.ResMap, patch jsonpatch.Patch) error {
|
||||
// transformJson6902 applies json6902 Patch to all the resources in the ResMap that match Target.
|
||||
func (p *PatchTransformerPlugin) transformJson6902(m resmap.ResMap) error {
|
||||
if p.Target == nil {
|
||||
return fmt.Errorf("must specify a target for patch %s", p.Patch)
|
||||
return fmt.Errorf("must specify a target for JSON patch %s", p.patchSource)
|
||||
}
|
||||
resources, err := m.Select(*p.Target)
|
||||
if err != nil {
|
||||
@@ -114,7 +133,7 @@ func (p *PatchTransformerPlugin) transformJson6902(m resmap.ResMap, patch jsonpa
|
||||
res.StorePreviousId()
|
||||
internalAnnotations := kioutil.GetInternalAnnotations(&res.RNode)
|
||||
err = res.ApplyFilter(patchjson6902.Filter{
|
||||
Patch: p.Patch,
|
||||
Patch: p.patchText,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -129,16 +148,17 @@ func (p *PatchTransformerPlugin) transformJson6902(m resmap.ResMap, patch jsonpa
|
||||
return nil
|
||||
}
|
||||
|
||||
// jsonPatchFromBytes loads a Json 6902 patch from
|
||||
// a bytes input
|
||||
func jsonPatchFromBytes(
|
||||
in []byte) (jsonpatch.Patch, error) {
|
||||
// jsonPatchFromBytes loads a Json 6902 patch from a bytes input
|
||||
func jsonPatchFromBytes(in []byte) (jsonpatch.Patch, error) {
|
||||
ops := string(in)
|
||||
if ops == "" {
|
||||
return nil, fmt.Errorf("empty json patch operations")
|
||||
}
|
||||
|
||||
if ops[0] != '[' {
|
||||
// TODO(5049):
|
||||
// In the case of multiple yaml documents, return error instead of ignoring all but first.
|
||||
// Details: https://github.com/kubernetes-sigs/kustomize/pull/5194#discussion_r1256686728
|
||||
jsonOps, err := yaml.YAMLToJSON(in)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Code generated by pluginator on PrefixTransformer; DO NOT EDIT.
|
||||
// pluginator {unknown 1970-01-01T00:00:00Z }
|
||||
// pluginator {(devel) unknown }
|
||||
|
||||
package builtins
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Code generated by pluginator on ReplacementTransformer; DO NOT EDIT.
|
||||
// pluginator {unknown 1970-01-01T00:00:00Z }
|
||||
// pluginator {(devel) unknown }
|
||||
|
||||
package builtins
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Code generated by pluginator on ReplicaCountTransformer; DO NOT EDIT.
|
||||
// pluginator {unknown 1970-01-01T00:00:00Z }
|
||||
// pluginator {(devel) unknown }
|
||||
|
||||
package builtins
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Code generated by pluginator on SecretGenerator; DO NOT EDIT.
|
||||
// pluginator {unknown 1970-01-01T00:00:00Z }
|
||||
// pluginator {(devel) unknown }
|
||||
|
||||
package builtins
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Code generated by pluginator on SortOrderTransformer; DO NOT EDIT.
|
||||
// pluginator {unknown 1970-01-01T00:00:00Z }
|
||||
// pluginator {(devel) unknown }
|
||||
|
||||
package builtins
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Code generated by pluginator on SuffixTransformer; DO NOT EDIT.
|
||||
// pluginator {unknown 1970-01-01T00:00:00Z }
|
||||
// pluginator {(devel) unknown }
|
||||
|
||||
package builtins
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// Code generated by pluginator on ValueAddTransformer; DO NOT EDIT.
|
||||
// pluginator {unknown 1970-01-01T00:00:00Z }
|
||||
// pluginator {(devel) unknown }
|
||||
|
||||
package builtins
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
. "sigs.k8s.io/kustomize/api/internal/generators"
|
||||
"sigs.k8s.io/kustomize/api/kv"
|
||||
"sigs.k8s.io/kustomize/api/loader"
|
||||
"sigs.k8s.io/kustomize/api/pkg/loader"
|
||||
valtest_test "sigs.k8s.io/kustomize/api/testutils/valtest"
|
||||
"sigs.k8s.io/kustomize/api/types"
|
||||
"sigs.k8s.io/kustomize/kyaml/filesys"
|
||||
|
||||
@@ -10,7 +10,7 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
. "sigs.k8s.io/kustomize/api/internal/generators"
|
||||
"sigs.k8s.io/kustomize/api/kv"
|
||||
"sigs.k8s.io/kustomize/api/loader"
|
||||
"sigs.k8s.io/kustomize/api/pkg/loader"
|
||||
valtest_test "sigs.k8s.io/kustomize/api/testutils/valtest"
|
||||
"sigs.k8s.io/kustomize/api/types"
|
||||
"sigs.k8s.io/kustomize/kyaml/filesys"
|
||||
|
||||
@@ -22,10 +22,16 @@ func ClonerUsingGitExec(repoSpec *RepoSpec) error {
|
||||
if err = r.run("init"); err != nil {
|
||||
return err
|
||||
}
|
||||
// git relative submodule need origin, see https://github.com/kubernetes-sigs/kustomize/issues/5131
|
||||
if err = r.run("remote", "add", "origin", repoSpec.CloneSpec()); err != nil {
|
||||
return err
|
||||
}
|
||||
ref := "HEAD"
|
||||
if repoSpec.Ref != "" {
|
||||
ref = repoSpec.Ref
|
||||
}
|
||||
// we use repoSpec.CloneSpec() instead of origin because on error,
|
||||
// the prior prints the actual repo url for the user.
|
||||
if err = r.run("fetch", "--depth=1", repoSpec.CloneSpec(), ref); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -370,8 +370,9 @@ func trimPrefixIgnoreCase(s, prefix string) (string, bool) {
|
||||
func findPathSeparator(hostPath string, acceptSCP bool) int {
|
||||
sepIndex := strings.Index(hostPath, pathSeparator)
|
||||
if acceptSCP {
|
||||
colonIndex := strings.Index(hostPath, ":")
|
||||
// The colon acts as a delimiter in scp-style ssh URLs only if not prefixed by '/'.
|
||||
if colonIndex := strings.Index(hostPath, ":"); colonIndex > 0 && colonIndex < sepIndex {
|
||||
if sepIndex == -1 || (colonIndex > 0 && colonIndex < sepIndex) {
|
||||
sepIndex = colonIndex
|
||||
}
|
||||
}
|
||||
|
||||
@@ -659,6 +659,26 @@ func TestNewRepoSpecFromUrl_Smoke(t *testing.T) {
|
||||
RepoPath: "kubernetes-sigs/kustomize",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "scp format gist url",
|
||||
input: "git@gist.github.com:bc7947cb727d7f9217e7862d961a1ffd.git",
|
||||
cloneSpec: "git@gist.github.com:bc7947cb727d7f9217e7862d961a1ffd.git",
|
||||
absPath: notCloned.String(),
|
||||
repoSpec: RepoSpec{
|
||||
Host: "git@gist.github.com:",
|
||||
RepoPath: "bc7947cb727d7f9217e7862d961a1ffd.git",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "https gist url",
|
||||
input: "https://gist.github.com/bc7947cb727d7f9217e7862d961a1ffd.git",
|
||||
cloneSpec: "https://gist.github.com/bc7947cb727d7f9217e7862d961a1ffd.git",
|
||||
absPath: notCloned.String(),
|
||||
repoSpec: RepoSpec{
|
||||
Host: "https://gist.github.com/",
|
||||
RepoPath: "bc7947cb727d7f9217e7862d961a1ffd.git",
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tc := range testcases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
// Copyright 2020 The Kubernetes Authors.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package image
|
||||
package image_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"sigs.k8s.io/kustomize/api/internal/image"
|
||||
)
|
||||
|
||||
func TestIsImageMatched(t *testing.T) {
|
||||
@@ -50,7 +51,7 @@ func TestIsImageMatched(t *testing.T) {
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.testName, func(t *testing.T) {
|
||||
assert.Equal(t, tc.isMatched, IsImageMatched(tc.value, tc.name))
|
||||
assert.Equal(t, tc.isMatched, image.IsImageMatched(tc.value, tc.name))
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -116,7 +117,7 @@ func TestSplit(t *testing.T) {
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.testName, func(t *testing.T) {
|
||||
name, tag, digest := Split(tc.value)
|
||||
name, tag, digest := image.Split(tc.value)
|
||||
assert.Equal(t, tc.name, name)
|
||||
assert.Equal(t, tc.tag, tag)
|
||||
assert.Equal(t, tc.digest, digest)
|
||||
@@ -25,7 +25,7 @@ func IsRemoteFile(path string) bool {
|
||||
return err == nil && (u.Scheme == "http" || u.Scheme == "https")
|
||||
}
|
||||
|
||||
// fileLoader is a kustomization's interface to files.
|
||||
// FileLoader is a kustomization's interface to files.
|
||||
//
|
||||
// The directory in which a kustomization file sits
|
||||
// is referred to below as the kustomization's _root_.
|
||||
@@ -38,49 +38,48 @@ func IsRemoteFile(path string) bool {
|
||||
//
|
||||
// * supplemental data paths
|
||||
//
|
||||
// `Load` is used to visit these paths.
|
||||
// `Load` is used to visit these paths.
|
||||
//
|
||||
// These paths refer to resources, patches,
|
||||
// data for ConfigMaps and Secrets, etc.
|
||||
// These paths refer to resources, patches,
|
||||
// data for ConfigMaps and Secrets, etc.
|
||||
//
|
||||
// The loadRestrictor may disallow certain paths
|
||||
// or classes of paths.
|
||||
// The loadRestrictor may disallow certain paths
|
||||
// or classes of paths.
|
||||
//
|
||||
// * bases (other kustomizations)
|
||||
//
|
||||
// `New` is used to load bases.
|
||||
// `New` is used to load bases.
|
||||
//
|
||||
// A base can be either a remote git repo URL, or
|
||||
// a directory specified relative to the current
|
||||
// root. In the former case, the repo is locally
|
||||
// cloned, and the new loader is rooted on a path
|
||||
// in that clone.
|
||||
// A base can be either a remote git repo URL, or
|
||||
// a directory specified relative to the current
|
||||
// root. In the former case, the repo is locally
|
||||
// cloned, and the new loader is rooted on a path
|
||||
// in that clone.
|
||||
//
|
||||
// As loaders create new loaders, a root history
|
||||
// is established, and used to disallow:
|
||||
// As loaders create new loaders, a root history
|
||||
// is established, and used to disallow:
|
||||
//
|
||||
// - A base that is a repository that, in turn,
|
||||
// specifies a base repository seen previously
|
||||
// in the loading stack (a cycle).
|
||||
// - A base that is a repository that, in turn,
|
||||
// specifies a base repository seen previously
|
||||
// in the loading stack (a cycle).
|
||||
//
|
||||
// - An overlay depending on a base positioned at
|
||||
// or above it. I.e. '../foo' is OK, but '.',
|
||||
// '..', '../..', etc. are disallowed. Allowing
|
||||
// such a base has no advantages and encourages
|
||||
// cycles, particularly if some future change
|
||||
// were to introduce globbing to file
|
||||
// specifications in the kustomization file.
|
||||
// - An overlay depending on a base positioned at
|
||||
// or above it. I.e. '../foo' is OK, but '.',
|
||||
// '..', '../..', etc. are disallowed. Allowing
|
||||
// such a base has no advantages and encourages
|
||||
// cycles, particularly if some future change
|
||||
// were to introduce globbing to file
|
||||
// specifications in the kustomization file.
|
||||
//
|
||||
// These restrictions assure that kustomizations
|
||||
// are self-contained and relocatable, and impose
|
||||
// some safety when relying on remote kustomizations,
|
||||
// e.g. a remotely loaded ConfigMap generator specified
|
||||
// to read from /etc/passwd will fail.
|
||||
//
|
||||
type fileLoader struct {
|
||||
type FileLoader struct {
|
||||
// Loader that spawned this loader.
|
||||
// Used to avoid cycles.
|
||||
referrer *fileLoader
|
||||
referrer *FileLoader
|
||||
|
||||
// An absolute, cleaned path to a directory.
|
||||
// The Load function will read non-absolute
|
||||
@@ -107,23 +106,9 @@ type fileLoader struct {
|
||||
cleaner func() error
|
||||
}
|
||||
|
||||
// NewFileLoaderAtCwd returns a loader that loads from PWD.
|
||||
// A convenience for kustomize edit commands.
|
||||
func NewFileLoaderAtCwd(fSys filesys.FileSystem) *fileLoader {
|
||||
return newLoaderOrDie(
|
||||
RestrictionRootOnly, fSys, filesys.SelfDir)
|
||||
}
|
||||
|
||||
// NewFileLoaderAtRoot returns a loader that loads from "/".
|
||||
// A convenience for tests.
|
||||
func NewFileLoaderAtRoot(fSys filesys.FileSystem) *fileLoader {
|
||||
return newLoaderOrDie(
|
||||
RestrictionRootOnly, fSys, filesys.Separator)
|
||||
}
|
||||
|
||||
// Repo returns the absolute path to the repo that contains Root if this fileLoader was created from a url
|
||||
// or the empty string otherwise.
|
||||
func (fl *fileLoader) Repo() string {
|
||||
func (fl *FileLoader) Repo() string {
|
||||
if fl.repoSpec != nil {
|
||||
return fl.repoSpec.Dir.String()
|
||||
}
|
||||
@@ -132,13 +117,13 @@ func (fl *fileLoader) Repo() string {
|
||||
|
||||
// Root returns the absolute path that is prepended to any
|
||||
// relative paths used in Load.
|
||||
func (fl *fileLoader) Root() string {
|
||||
func (fl *FileLoader) Root() string {
|
||||
return fl.root.String()
|
||||
}
|
||||
|
||||
func newLoaderOrDie(
|
||||
func NewLoaderOrDie(
|
||||
lr LoadRestrictorFunc,
|
||||
fSys filesys.FileSystem, path string) *fileLoader {
|
||||
fSys filesys.FileSystem, path string) *FileLoader {
|
||||
root, err := filesys.ConfirmDir(fSys, path)
|
||||
if err != nil {
|
||||
log.Fatalf("unable to make loader at '%s'; %v", path, err)
|
||||
@@ -147,12 +132,12 @@ func newLoaderOrDie(
|
||||
lr, root, fSys, nil, git.ClonerUsingGitExec)
|
||||
}
|
||||
|
||||
// newLoaderAtConfirmedDir returns a new fileLoader with given root.
|
||||
// newLoaderAtConfirmedDir returns a new FileLoader with given root.
|
||||
func newLoaderAtConfirmedDir(
|
||||
lr LoadRestrictorFunc,
|
||||
root filesys.ConfirmedDir, fSys filesys.FileSystem,
|
||||
referrer *fileLoader, cloner git.Cloner) *fileLoader {
|
||||
return &fileLoader{
|
||||
referrer *FileLoader, cloner git.Cloner) *FileLoader {
|
||||
return &FileLoader{
|
||||
loadRestrictor: lr,
|
||||
root: root,
|
||||
referrer: referrer,
|
||||
@@ -164,7 +149,7 @@ func newLoaderAtConfirmedDir(
|
||||
|
||||
// New returns a new Loader, rooted relative to current loader,
|
||||
// or rooted in a temp directory holding a git repo clone.
|
||||
func (fl *fileLoader) New(path string) (ifc.Loader, error) {
|
||||
func (fl *FileLoader) New(path string) (ifc.Loader, error) {
|
||||
if path == "" {
|
||||
return nil, errors.Errorf("new root cannot be empty")
|
||||
}
|
||||
@@ -200,7 +185,7 @@ func (fl *fileLoader) New(path string) (ifc.Loader, error) {
|
||||
// directory holding a cloned git repo.
|
||||
func newLoaderAtGitClone(
|
||||
repoSpec *git.RepoSpec, fSys filesys.FileSystem,
|
||||
referrer *fileLoader, cloner git.Cloner) (ifc.Loader, error) {
|
||||
referrer *FileLoader, cloner git.Cloner) (ifc.Loader, error) {
|
||||
cleaner := repoSpec.Cleaner(fSys)
|
||||
err := cloner(repoSpec)
|
||||
if err != nil {
|
||||
@@ -229,7 +214,7 @@ func newLoaderAtGitClone(
|
||||
return nil, fmt.Errorf("%q refers to directory outside of repo %q", repoSpec.AbsPath(),
|
||||
repoSpec.CloneDir())
|
||||
}
|
||||
return &fileLoader{
|
||||
return &FileLoader{
|
||||
// Clones never allowed to escape root.
|
||||
loadRestrictor: RestrictionRootOnly,
|
||||
root: root,
|
||||
@@ -241,7 +226,7 @@ func newLoaderAtGitClone(
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (fl *fileLoader) errIfGitContainmentViolation(
|
||||
func (fl *FileLoader) errIfGitContainmentViolation(
|
||||
base filesys.ConfirmedDir) error {
|
||||
containingRepo := fl.containingRepo()
|
||||
if containingRepo == nil {
|
||||
@@ -259,7 +244,7 @@ func (fl *fileLoader) errIfGitContainmentViolation(
|
||||
|
||||
// Looks back through referrers for a git repo, returning nil
|
||||
// if none found.
|
||||
func (fl *fileLoader) containingRepo() *git.RepoSpec {
|
||||
func (fl *FileLoader) containingRepo() *git.RepoSpec {
|
||||
if fl.repoSpec != nil {
|
||||
return fl.repoSpec
|
||||
}
|
||||
@@ -271,7 +256,7 @@ func (fl *fileLoader) containingRepo() *git.RepoSpec {
|
||||
|
||||
// errIfArgEqualOrHigher tests whether the argument,
|
||||
// is equal to or above the root of any ancestor.
|
||||
func (fl *fileLoader) errIfArgEqualOrHigher(
|
||||
func (fl *FileLoader) errIfArgEqualOrHigher(
|
||||
candidateRoot filesys.ConfirmedDir) error {
|
||||
if fl.root.HasPrefix(candidateRoot) {
|
||||
return fmt.Errorf(
|
||||
@@ -288,7 +273,7 @@ func (fl *fileLoader) errIfArgEqualOrHigher(
|
||||
// I.e. Allow a distinction between git URI with
|
||||
// path foo and tag bar and a git URI with the same
|
||||
// path but a different tag?
|
||||
func (fl *fileLoader) errIfRepoCycle(newRepoSpec *git.RepoSpec) error {
|
||||
func (fl *FileLoader) errIfRepoCycle(newRepoSpec *git.RepoSpec) error {
|
||||
// TODO(monopole): Use parsed data instead of Raw().
|
||||
if fl.repoSpec != nil &&
|
||||
strings.HasPrefix(fl.repoSpec.Raw(), newRepoSpec.Raw()) {
|
||||
@@ -305,7 +290,7 @@ func (fl *fileLoader) errIfRepoCycle(newRepoSpec *git.RepoSpec) error {
|
||||
// Load returns the content of file at the given path,
|
||||
// else an error. Relative paths are taken relative
|
||||
// to the root.
|
||||
func (fl *fileLoader) Load(path string) ([]byte, error) {
|
||||
func (fl *FileLoader) Load(path string) ([]byte, error) {
|
||||
if IsRemoteFile(path) {
|
||||
return fl.httpClientGetContent(path)
|
||||
}
|
||||
@@ -319,7 +304,7 @@ func (fl *fileLoader) Load(path string) ([]byte, error) {
|
||||
return fl.fSys.ReadFile(path)
|
||||
}
|
||||
|
||||
func (fl *fileLoader) httpClientGetContent(path string) ([]byte, error) {
|
||||
func (fl *FileLoader) httpClientGetContent(path string) ([]byte, error) {
|
||||
var hc *http.Client
|
||||
if fl.http != nil {
|
||||
hc = fl.http
|
||||
@@ -344,6 +329,6 @@ func (fl *fileLoader) httpClientGetContent(path string) ([]byte, error) {
|
||||
}
|
||||
|
||||
// Cleanup runs the cleaner.
|
||||
func (fl *fileLoader) Cleanup() error {
|
||||
func (fl *FileLoader) Cleanup() error {
|
||||
return fl.cleaner()
|
||||
}
|
||||
@@ -31,6 +31,11 @@ func TestIsRemoteFile(t *testing.T) {
|
||||
"https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/examples/helloWorld/configMap.yaml",
|
||||
true,
|
||||
},
|
||||
"malformed https": {
|
||||
// TODO(annasong): Maybe we want to fix this. Needs more research.
|
||||
"https:/raw.githubusercontent.com/kubernetes-sigs/kustomize/master/examples/helloWorld/configMap.yaml",
|
||||
true,
|
||||
},
|
||||
"https dir": {
|
||||
"https://github.com/kubernetes-sigs/kustomize//examples/helloWorld/",
|
||||
true,
|
||||
@@ -88,8 +93,9 @@ func MakeFakeFs(td []testData) filesys.FileSystem {
|
||||
return fSys
|
||||
}
|
||||
|
||||
func makeLoader() *fileLoader {
|
||||
return NewFileLoaderAtRoot(MakeFakeFs(testCases))
|
||||
func makeLoader() *FileLoader {
|
||||
return NewLoaderOrDie(
|
||||
RestrictionRootOnly, MakeFakeFs(testCases), filesys.Separator)
|
||||
}
|
||||
|
||||
func TestLoaderLoad(t *testing.T) {
|
||||
@@ -196,13 +202,52 @@ func TestLoaderBadRelative(t *testing.T) {
|
||||
require.Error(err)
|
||||
}
|
||||
|
||||
func TestLoaderMisc(t *testing.T) {
|
||||
l := makeLoader()
|
||||
_, err := l.New("")
|
||||
func TestNewEmptyLoader(t *testing.T) {
|
||||
_, err := makeLoader().New("")
|
||||
require.Error(t, err)
|
||||
}
|
||||
|
||||
_, err = l.New("https://google.com/project")
|
||||
require.Error(t, err)
|
||||
func TestNewRemoteLoaderDoesNotExist(t *testing.T) {
|
||||
_, err := makeLoader().New("https://example.com/org/repo")
|
||||
require.ErrorContains(t, err, "fetch")
|
||||
}
|
||||
|
||||
func TestLoaderLocalScheme(t *testing.T) {
|
||||
// It is unlikely but possible for a reference with a url scheme to
|
||||
// actually refer to a local file or directory.
|
||||
t.Run("file", func(t *testing.T) {
|
||||
fSys, dir := setupOnDisk(t)
|
||||
parts := []string{
|
||||
"ssh:",
|
||||
"resource.yaml",
|
||||
}
|
||||
require.NoError(t, fSys.Mkdir(dir.Join(parts[0])))
|
||||
const content = "resource config"
|
||||
require.NoError(t, fSys.WriteFile(
|
||||
dir.Join(filepath.Join(parts...)),
|
||||
[]byte(content),
|
||||
))
|
||||
actualContent, err := NewLoaderOrDie(RestrictionRootOnly,
|
||||
fSys,
|
||||
dir.String(),
|
||||
).Load(strings.Join(parts, "//"))
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, content, string(actualContent))
|
||||
})
|
||||
t.Run("directory", func(t *testing.T) {
|
||||
fSys, dir := setupOnDisk(t)
|
||||
parts := []string{
|
||||
"https:",
|
||||
"root",
|
||||
}
|
||||
require.NoError(t, fSys.MkdirAll(dir.Join(filepath.Join(parts...))))
|
||||
ldr, err := NewLoaderOrDie(RestrictionRootOnly,
|
||||
fSys,
|
||||
dir.String(),
|
||||
).New(strings.Join(parts, "//"))
|
||||
require.NoError(t, err)
|
||||
require.Empty(t, ldr.Repo())
|
||||
})
|
||||
}
|
||||
|
||||
const (
|
||||
@@ -212,17 +257,17 @@ const (
|
||||
|
||||
// Create a structure like this
|
||||
//
|
||||
// /tmp/kustomize-test-random
|
||||
// ├── base
|
||||
// │ ├── okayData
|
||||
// │ ├── symLinkToOkayData -> okayData
|
||||
// │ └── symLinkToExteriorData -> ../exteriorData
|
||||
// └── exteriorData
|
||||
//
|
||||
// /tmp/kustomize-test-random
|
||||
// ├── base
|
||||
// │ ├── okayData
|
||||
// │ ├── symLinkToOkayData -> okayData
|
||||
// │ └── symLinkToExteriorData -> ../exteriorData
|
||||
// └── exteriorData
|
||||
func commonSetupForLoaderRestrictionTest(t *testing.T) (string, filesys.FileSystem) {
|
||||
t.Helper()
|
||||
dir := t.TempDir()
|
||||
fSys := filesys.MakeFsOnDisk()
|
||||
fSys, tmpDir := setupOnDisk(t)
|
||||
dir := tmpDir.String()
|
||||
|
||||
fSys.Mkdir(filepath.Join(dir, "base"))
|
||||
|
||||
fSys.WriteFile(
|
||||
@@ -278,7 +323,7 @@ func TestRestrictionRootOnlyInRealLoader(t *testing.T) {
|
||||
|
||||
var l ifc.Loader
|
||||
|
||||
l = newLoaderOrDie(RestrictionRootOnly, fSys, dir)
|
||||
l = NewLoaderOrDie(RestrictionRootOnly, fSys, dir)
|
||||
|
||||
l = doSanityChecksAndDropIntoBase(t, l)
|
||||
|
||||
@@ -299,7 +344,7 @@ func TestRestrictionNoneInRealLoader(t *testing.T) {
|
||||
|
||||
var l ifc.Loader
|
||||
|
||||
l = newLoaderOrDie(RestrictionNone, fSys, dir)
|
||||
l = NewLoaderOrDie(RestrictionNone, fSys, dir)
|
||||
|
||||
l = doSanityChecksAndDropIntoBase(t, l)
|
||||
|
||||
@@ -398,7 +443,7 @@ func TestLoaderDisallowsLocalBaseFromRemoteOverlay(t *testing.T) {
|
||||
|
||||
// Establish that a local overlay can navigate
|
||||
// to the local bases.
|
||||
l1 = newLoaderOrDie(
|
||||
l1 = NewLoaderOrDie(
|
||||
RestrictionRootOnly, fSys, cloneRoot+"/foo/overlay")
|
||||
require.Equal(cloneRoot+"/foo/overlay", l1.Root())
|
||||
|
||||
@@ -446,12 +491,8 @@ func TestLoaderDisallowsLocalBaseFromRemoteOverlay(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestLoaderDisallowsRemoteBaseExitRepo(t *testing.T) {
|
||||
fSys := filesys.MakeFsOnDisk()
|
||||
dir, err := filesys.NewTmpConfirmedDir()
|
||||
require.NoError(t, err)
|
||||
t.Cleanup(func() {
|
||||
_ = fSys.RemoveAll(dir.String())
|
||||
})
|
||||
fSys, dir := setupOnDisk(t)
|
||||
|
||||
repo := dir.Join("repo")
|
||||
require.NoError(t, fSys.Mkdir(repo))
|
||||
|
||||
@@ -560,7 +601,8 @@ func TestLoaderHTTP(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
l1 := NewFileLoaderAtRoot(MakeFakeFs(testCasesFile))
|
||||
l1 := NewLoaderOrDie(
|
||||
RestrictionRootOnly, MakeFakeFs(testCasesFile), filesys.Separator)
|
||||
require.Equal("/", l1.Root())
|
||||
|
||||
for _, x := range testCasesFile {
|
||||
@@ -618,3 +660,19 @@ func TestLoaderHTTP(t *testing.T) {
|
||||
require.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
// setupOnDisk sets up a file system on disk and directory that is cleaned after
|
||||
// test completion.
|
||||
// TODO(annasong): Move all loader tests that require real file system into
|
||||
// api/krusty.
|
||||
func setupOnDisk(t *testing.T) (filesys.FileSystem, filesys.ConfirmedDir) {
|
||||
t.Helper()
|
||||
|
||||
fSys := filesys.MakeFsOnDisk()
|
||||
dir, err := filesys.NewTmpConfirmedDir()
|
||||
require.NoError(t, err)
|
||||
t.Cleanup(func() {
|
||||
_ = fSys.RemoveAll(dir.String())
|
||||
})
|
||||
return fSys, dir
|
||||
}
|
||||
@@ -131,6 +131,7 @@ func (lbp *localizeBuiltinPlugins) localizeAll(node *yaml.RNode) error {
|
||||
// We rely on the build command to throw errors for nodes in
|
||||
// built-in plugins that are sequences when expected to be scalar,
|
||||
// and vice versa.
|
||||
//nolint: exhaustive
|
||||
switch node.YNode().Kind {
|
||||
case yaml.SequenceNode:
|
||||
return errors.Wrap(node.VisitElements(lbp.localizeScalar))
|
||||
|
||||
@@ -11,8 +11,8 @@ import (
|
||||
|
||||
"sigs.k8s.io/kustomize/api/ifc"
|
||||
"sigs.k8s.io/kustomize/api/internal/generators"
|
||||
"sigs.k8s.io/kustomize/api/internal/loader"
|
||||
"sigs.k8s.io/kustomize/api/internal/target"
|
||||
"sigs.k8s.io/kustomize/api/loader"
|
||||
"sigs.k8s.io/kustomize/api/provider"
|
||||
"sigs.k8s.io/kustomize/api/resmap"
|
||||
"sigs.k8s.io/kustomize/api/types"
|
||||
|
||||
@@ -263,7 +263,7 @@ suffix: invalid`,
|
||||
|
||||
_, err := Run("/a", "", "", fSysTest)
|
||||
require.EqualError(t, err,
|
||||
`unable to localize target "/a": invalid Kustomization: error unmarshaling JSON: while decoding JSON: json: unknown field "suffix"`)
|
||||
`unable to localize target "/a": invalid Kustomization: json: unknown field "suffix"`)
|
||||
|
||||
checkFSys(t, fSysExpected, fSysTest)
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
|
||||
"sigs.k8s.io/kustomize/api/ifc"
|
||||
"sigs.k8s.io/kustomize/api/internal/git"
|
||||
"sigs.k8s.io/kustomize/api/loader"
|
||||
"sigs.k8s.io/kustomize/api/internal/loader"
|
||||
"sigs.k8s.io/kustomize/kyaml/errors"
|
||||
"sigs.k8s.io/kustomize/kyaml/filesys"
|
||||
)
|
||||
|
||||
@@ -6,6 +6,7 @@ package localizer_test
|
||||
import (
|
||||
"bytes"
|
||||
"log"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
@@ -37,6 +38,9 @@ func TestLocalLoadNewAndCleanup(t *testing.T) {
|
||||
|
||||
var buf bytes.Buffer
|
||||
log.SetOutput(&buf)
|
||||
defer func() {
|
||||
log.SetOutput(os.Stderr)
|
||||
}()
|
||||
// typical setup
|
||||
ldr, args, err := NewLoader("a", "/", "/newDir", fSys)
|
||||
req.NoError(err)
|
||||
@@ -223,6 +227,9 @@ func TestNewLocLoaderFails(t *testing.T) {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
var buf bytes.Buffer
|
||||
log.SetOutput(&buf)
|
||||
defer func() {
|
||||
log.SetOutput(os.Stderr)
|
||||
}()
|
||||
|
||||
_, _, err := NewLoader(params.target, params.scope, params.dest, makeMemoryFs(t))
|
||||
require.Error(t, err)
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"sigs.k8s.io/kustomize/api/loader"
|
||||
"sigs.k8s.io/kustomize/api/internal/loader"
|
||||
"sigs.k8s.io/kustomize/api/types"
|
||||
"sigs.k8s.io/kustomize/kyaml/filesys"
|
||||
"sigs.k8s.io/kustomize/kyaml/resid"
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
"sort"
|
||||
|
||||
"sigs.k8s.io/kustomize/api/ifc"
|
||||
"sigs.k8s.io/kustomize/api/konfig/builtinpluginconsts"
|
||||
"sigs.k8s.io/kustomize/api/internal/konfig/builtinpluginconsts"
|
||||
"sigs.k8s.io/kustomize/api/types"
|
||||
"sigs.k8s.io/kustomize/kyaml/errors"
|
||||
)
|
||||
|
||||
@@ -10,10 +10,10 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
fLdr "sigs.k8s.io/kustomize/api/internal/loader"
|
||||
. "sigs.k8s.io/kustomize/api/internal/plugins/execplugin"
|
||||
pLdr "sigs.k8s.io/kustomize/api/internal/plugins/loader"
|
||||
"sigs.k8s.io/kustomize/api/internal/plugins/utils"
|
||||
fLdr "sigs.k8s.io/kustomize/api/loader"
|
||||
"sigs.k8s.io/kustomize/api/provider"
|
||||
"sigs.k8s.io/kustomize/api/resmap"
|
||||
"sigs.k8s.io/kustomize/api/types"
|
||||
|
||||
@@ -7,8 +7,8 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"sigs.k8s.io/kustomize/api/internal/loader"
|
||||
. "sigs.k8s.io/kustomize/api/internal/plugins/loader"
|
||||
"sigs.k8s.io/kustomize/api/loader"
|
||||
"sigs.k8s.io/kustomize/api/provider"
|
||||
"sigs.k8s.io/kustomize/api/resmap"
|
||||
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
|
||||
|
||||
@@ -13,12 +13,12 @@ import (
|
||||
"sigs.k8s.io/kustomize/api/internal/accumulator"
|
||||
"sigs.k8s.io/kustomize/api/internal/builtins"
|
||||
"sigs.k8s.io/kustomize/api/internal/kusterr"
|
||||
load "sigs.k8s.io/kustomize/api/internal/loader"
|
||||
"sigs.k8s.io/kustomize/api/internal/plugins/builtinconfig"
|
||||
"sigs.k8s.io/kustomize/api/internal/plugins/builtinhelpers"
|
||||
"sigs.k8s.io/kustomize/api/internal/plugins/loader"
|
||||
"sigs.k8s.io/kustomize/api/internal/utils"
|
||||
"sigs.k8s.io/kustomize/api/konfig"
|
||||
load "sigs.k8s.io/kustomize/api/loader"
|
||||
"sigs.k8s.io/kustomize/api/resmap"
|
||||
"sigs.k8s.io/kustomize/api/resource"
|
||||
"sigs.k8s.io/kustomize/api/types"
|
||||
@@ -73,6 +73,11 @@ func (kt *KustTarget) Load() error {
|
||||
|
||||
k.FixKustomization()
|
||||
|
||||
// check that Kustomization is empty
|
||||
if err := k.CheckEmpty(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
errs := k.EnforceFields()
|
||||
if len(errs) > 0 {
|
||||
return fmt.Errorf(
|
||||
@@ -197,10 +202,6 @@ func (kt *KustTarget) accumulateTarget(ra *accumulator.ResAccumulator) (
|
||||
if err != nil {
|
||||
return nil, errors.WrapPrefixf(err, "accumulating resources")
|
||||
}
|
||||
ra, err = kt.accumulateComponents(ra, kt.kustomization.Components)
|
||||
if err != nil {
|
||||
return nil, errors.WrapPrefixf(err, "accumulating components")
|
||||
}
|
||||
tConfig, err := builtinconfig.MakeTransformerConfig(
|
||||
kt.ldr, kt.kustomization.Configurations)
|
||||
if err != nil {
|
||||
@@ -225,6 +226,14 @@ func (kt *KustTarget) accumulateTarget(ra *accumulator.ResAccumulator) (
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// components are expected to execute after reading resources and adding generators ,before applying transformers and validation.
|
||||
// https://github.com/kubernetes-sigs/kustomize/pull/5170#discussion_r1212101287
|
||||
ra, err = kt.accumulateComponents(ra, kt.kustomization.Components)
|
||||
if err != nil {
|
||||
return nil, errors.WrapPrefixf(err, "accumulating components")
|
||||
}
|
||||
|
||||
err = kt.runTransformers(ra)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
"sigs.k8s.io/kustomize/api/ifc"
|
||||
. "sigs.k8s.io/kustomize/api/internal/target"
|
||||
"sigs.k8s.io/kustomize/api/loader"
|
||||
"sigs.k8s.io/kustomize/api/pkg/loader"
|
||||
"sigs.k8s.io/kustomize/api/provider"
|
||||
"sigs.k8s.io/kustomize/api/resmap"
|
||||
"sigs.k8s.io/kustomize/api/resource"
|
||||
@@ -79,6 +79,7 @@ func TestLoad(t *testing.T) {
|
||||
k: types.Kustomization{
|
||||
TypeMeta: expectedTypeMeta,
|
||||
},
|
||||
errContains: "kustomization.yaml is empty",
|
||||
},
|
||||
"nonsenseLatin": {
|
||||
errContains: "found a tab character that violates indentation",
|
||||
|
||||
@@ -6,9 +6,9 @@ package target_test
|
||||
import (
|
||||
"testing"
|
||||
|
||||
fLdr "sigs.k8s.io/kustomize/api/internal/loader"
|
||||
pLdr "sigs.k8s.io/kustomize/api/internal/plugins/loader"
|
||||
"sigs.k8s.io/kustomize/api/internal/target"
|
||||
fLdr "sigs.k8s.io/kustomize/api/loader"
|
||||
"sigs.k8s.io/kustomize/api/provider"
|
||||
"sigs.k8s.io/kustomize/api/resmap"
|
||||
valtest_test "sigs.k8s.io/kustomize/api/testutils/valtest"
|
||||
|
||||
@@ -4,15 +4,31 @@
|
||||
package krusty_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
. "sigs.k8s.io/kustomize/api/internal/target"
|
||||
"sigs.k8s.io/kustomize/api/konfig"
|
||||
"sigs.k8s.io/kustomize/api/krusty"
|
||||
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
|
||||
)
|
||||
|
||||
const validResource = `
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: myService
|
||||
spec:
|
||||
selector:
|
||||
backend: bungie
|
||||
ports:
|
||||
- port: 7002
|
||||
`
|
||||
|
||||
func TestTargetMustHaveKustomizationFile(t *testing.T) {
|
||||
th := kusttest_test.MakeHarness(t)
|
||||
th.WriteF("service.yaml", `
|
||||
@@ -59,17 +75,7 @@ func TestBaseMustHaveKustomizationFile(t *testing.T) {
|
||||
resources:
|
||||
- base
|
||||
`)
|
||||
th.WriteF("base/service.yaml", `
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: myService
|
||||
spec:
|
||||
selector:
|
||||
backend: bungie
|
||||
ports:
|
||||
- port: 7002
|
||||
`)
|
||||
th.WriteF("base/service.yaml", validResource)
|
||||
err := th.RunWithErr(".", th.MakeDefaultOptions())
|
||||
if err == nil {
|
||||
t.Fatalf("expected an error")
|
||||
@@ -160,3 +166,145 @@ spec:
|
||||
secretName: cert-tls
|
||||
`)
|
||||
}
|
||||
|
||||
func TestAccumulateResourcesErrors(t *testing.T) {
|
||||
type testcase struct {
|
||||
name string
|
||||
resource string
|
||||
isAbsolute bool
|
||||
files map[string]string
|
||||
// errFile, errDir are regex for the expected error message output
|
||||
// when kustomize tries to accumulate resource as file and dir,
|
||||
// respectively. The test substitutes occurrences of "%s" in the
|
||||
// error strings with the absolute path where kustomize looks for it.
|
||||
errFile, errDir string
|
||||
}
|
||||
populateAbsolutePaths := func(tc testcase, dir string) testcase {
|
||||
filePaths := make(map[string]string, len(tc.files)+1)
|
||||
for file, content := range tc.files {
|
||||
filePaths[filepath.Join(dir, file)] = content
|
||||
}
|
||||
resourcePath := filepath.Join(dir, tc.resource)
|
||||
if tc.isAbsolute {
|
||||
tc.resource = resourcePath
|
||||
}
|
||||
filePaths[filepath.Join(dir, "kustomization.yaml")] = fmt.Sprintf(`
|
||||
resources:
|
||||
- %s
|
||||
`, tc.resource)
|
||||
tc.files = filePaths
|
||||
regPath := regexp.QuoteMeta(resourcePath)
|
||||
tc.errFile = strings.ReplaceAll(tc.errFile, "%s", regPath)
|
||||
tc.errDir = strings.ReplaceAll(tc.errDir, "%s", regPath)
|
||||
return tc
|
||||
}
|
||||
buildError := func(tc testcase) string {
|
||||
const (
|
||||
prefix = "accumulating resources"
|
||||
filePrefixf = "accumulating resources from '%s'"
|
||||
fileWrapperIfDirf = "accumulation err='%s'"
|
||||
separator = ": "
|
||||
)
|
||||
parts := []string{
|
||||
prefix,
|
||||
strings.Join([]string{
|
||||
fmt.Sprintf(filePrefixf, regexp.QuoteMeta(tc.resource)),
|
||||
tc.errFile,
|
||||
}, separator),
|
||||
}
|
||||
if tc.errDir != "" {
|
||||
parts[1] = fmt.Sprintf(fileWrapperIfDirf, parts[1])
|
||||
parts = append(parts, tc.errDir)
|
||||
}
|
||||
return strings.Join(parts, separator)
|
||||
}
|
||||
for _, test := range []testcase{
|
||||
{
|
||||
name: "remote file not considered repo",
|
||||
// The example.com second-level domain is reserved and
|
||||
// safe to access, see RFC 2606.
|
||||
resource: "https://example.com/segments-too-few-to-be-repo",
|
||||
// It's acceptable for the error output of a remote file-like
|
||||
// resource to not indicate the resource's status as a
|
||||
// local directory. Though it is possible for a remote file-like
|
||||
// resource to be a local directory, it is very unlikely.
|
||||
errFile: `HTTP Error: status code 404 \(Not Found\)\z`,
|
||||
},
|
||||
{
|
||||
name: "remote file qualifies as repo",
|
||||
resource: "https://example.com/long/enough/to/have/org/and/repo",
|
||||
// TODO(4788): This error message is technically wrong. Just
|
||||
// because we fail to GET a resource does not mean the resource is
|
||||
// not a remote file. We should return the GET status code as well.
|
||||
errFile: "URL is a git repository",
|
||||
errDir: `failed to run \S+/git fetch --depth=1 .+`,
|
||||
},
|
||||
{
|
||||
name: "local file qualifies as repo",
|
||||
// The .example top level domain is reserved for example purposes,
|
||||
// see RFC 2606.
|
||||
resource: "package@v1.28.0.example/configs/base",
|
||||
errFile: `evalsymlink failure on '%s' .+`,
|
||||
errDir: `failed to run \S+/git fetch --depth=1 .+`,
|
||||
},
|
||||
{
|
||||
name: "relative path does not exist",
|
||||
resource: "file-or-directory",
|
||||
errFile: `evalsymlink failure on '%s' .+`,
|
||||
errDir: `must build at directory: not a valid directory: evalsymlink failure .+`,
|
||||
},
|
||||
{
|
||||
name: "absolute path does not exist",
|
||||
resource: "file-or-directory",
|
||||
isAbsolute: true,
|
||||
errFile: `evalsymlink failure on '%s' .+`,
|
||||
errDir: `new root '%s' cannot be absolute`,
|
||||
},
|
||||
{
|
||||
name: "relative file violates restrictions",
|
||||
resource: "../base/resource.yaml",
|
||||
files: map[string]string{
|
||||
"../base/resource.yaml": validResource,
|
||||
},
|
||||
errFile: "security; file '%s' is not in or below .+",
|
||||
// TODO(4348): Over-inclusion of directory error message when we
|
||||
// know resource is file.
|
||||
errDir: "must build at directory: '%s': file is not directory",
|
||||
},
|
||||
{
|
||||
name: "absolute file violates restrictions",
|
||||
resource: "../base/resource.yaml",
|
||||
isAbsolute: true,
|
||||
files: map[string]string{
|
||||
"../base/resource.yaml": validResource,
|
||||
},
|
||||
errFile: "security; file '%s' is not in or below .+",
|
||||
// TODO(4348): Over-inclusion of directory error message when we
|
||||
// know resource is file.
|
||||
errDir: `new root '%s' cannot be absolute`,
|
||||
},
|
||||
} {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
// Should use real file system to indicate that we are creating
|
||||
// new temporary directories on disk when we attempt to fetch repos.
|
||||
fs, tmpDir := kusttest_test.Setup(t)
|
||||
root := tmpDir.Join("root")
|
||||
require.NoError(t, fs.Mkdir(root))
|
||||
|
||||
test = populateAbsolutePaths(test, root)
|
||||
for file, content := range test.files {
|
||||
dir := filepath.Dir(file)
|
||||
require.NoError(t, fs.MkdirAll(dir))
|
||||
require.NoError(t, fs.WriteFile(file, []byte(content)))
|
||||
}
|
||||
|
||||
b := krusty.MakeKustomizer(krusty.MakeDefaultOptions())
|
||||
_, err := b.Run(fs, root)
|
||||
require.Regexp(t, buildError(test), err.Error())
|
||||
})
|
||||
}
|
||||
// TODO(annasong): add tests that check accumulateResources errors for
|
||||
// - repos
|
||||
// - local directories
|
||||
// - files that yield malformed yaml errors
|
||||
}
|
||||
|
||||
@@ -8,8 +8,8 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"sigs.k8s.io/kustomize/api/internal/loader"
|
||||
"sigs.k8s.io/kustomize/api/konfig"
|
||||
"sigs.k8s.io/kustomize/api/loader"
|
||||
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
|
||||
)
|
||||
|
||||
@@ -39,7 +39,7 @@ resources:
|
||||
- deploy.yaml
|
||||
configMapGenerator:
|
||||
- name: my-configmap
|
||||
literals:
|
||||
literals:
|
||||
- testValue=purple
|
||||
- otherValue=green
|
||||
`)
|
||||
@@ -64,7 +64,7 @@ resources:
|
||||
configMapGenerator:
|
||||
- name: my-configmap
|
||||
behavior: merge
|
||||
literals:
|
||||
literals:
|
||||
- testValue=blue
|
||||
- compValue=red
|
||||
`)
|
||||
@@ -154,7 +154,7 @@ spec:
|
||||
configMapGenerator:
|
||||
- name: my-configmap
|
||||
behavior: merge
|
||||
literals:
|
||||
literals:
|
||||
- otherValue=orange
|
||||
`),
|
||||
writeK("prod", `
|
||||
@@ -319,7 +319,7 @@ resources:
|
||||
configMapGenerator:
|
||||
- name: my-configmap
|
||||
behavior: merge
|
||||
literals:
|
||||
literals:
|
||||
- compValue=red
|
||||
- testValue=blue
|
||||
`),
|
||||
@@ -350,7 +350,7 @@ kind: Component
|
||||
configMapGenerator:
|
||||
- name: my-configmap
|
||||
behavior: merge
|
||||
literals:
|
||||
literals:
|
||||
- otherValue=orange
|
||||
`),
|
||||
},
|
||||
@@ -562,7 +562,7 @@ kind: Component
|
||||
configMapGenerator:
|
||||
- name: my-configmap
|
||||
behavior: merge
|
||||
literals:
|
||||
literals:
|
||||
- otherValue=orange
|
||||
`),
|
||||
},
|
||||
@@ -657,3 +657,113 @@ components:
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestOrderOfAccumulatedComponent(t *testing.T) {
|
||||
tests := map[string]struct {
|
||||
input []FileGen
|
||||
expectedOutput string
|
||||
}{
|
||||
"components_using_a_generated_resource_by_configMapGenerator": {
|
||||
input: []FileGen{
|
||||
writeK("", `
|
||||
resources:
|
||||
- resource.yaml
|
||||
components:
|
||||
- components
|
||||
configMapGenerator:
|
||||
- name: generated-resource
|
||||
literals:
|
||||
- key=value
|
||||
options:
|
||||
disableNameSuffixHash: true`),
|
||||
writeF("resource.yaml", `
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: config-from-resources
|
||||
data:
|
||||
foo: bar`),
|
||||
writeC("/components", `
|
||||
apiVersion: kustomize.config.k8s.io/v1alpha1
|
||||
kind: Component
|
||||
nameSuffix: -suffix
|
||||
`),
|
||||
},
|
||||
expectedOutput: `
|
||||
apiVersion: v1
|
||||
data:
|
||||
foo: bar
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: config-from-resources-suffix
|
||||
---
|
||||
apiVersion: v1
|
||||
data:
|
||||
key: value
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: generated-resource-suffix
|
||||
`},
|
||||
"components_are_applied_before_replacements_transformer_applied": {
|
||||
input: []FileGen{
|
||||
writeK("", `
|
||||
resources:
|
||||
- resource.yaml
|
||||
components:
|
||||
- components
|
||||
replacements:
|
||||
- source:
|
||||
kind: Pod
|
||||
name: myapp-pod
|
||||
fieldPath: metadata.namespace
|
||||
targets:
|
||||
- select:
|
||||
kind: Pod
|
||||
name: myapp-pod
|
||||
fieldPaths:
|
||||
- spec.containers.[name=myapp-container].env.[name=CURRENT_POD_NAMESPACE].value`),
|
||||
writeF("resource.yaml", `
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: myapp-pod
|
||||
namespace: dev-assa
|
||||
spec:
|
||||
containers:
|
||||
- image: busybox
|
||||
name: myapp-container
|
||||
env:
|
||||
- name: CURRENT_POD_NAMESPACE
|
||||
value: "$(PLACEHOLDER)"`),
|
||||
writeC("/components", `
|
||||
apiVersion: kustomize.config.k8s.io/v1alpha1
|
||||
kind: Component
|
||||
namespace: kustomize-namespace`),
|
||||
},
|
||||
expectedOutput: `
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: myapp-pod
|
||||
namespace: kustomize-namespace
|
||||
spec:
|
||||
containers:
|
||||
- env:
|
||||
- name: CURRENT_POD_NAMESPACE
|
||||
value: kustomize-namespace
|
||||
image: busybox
|
||||
name: myapp-container
|
||||
`},
|
||||
}
|
||||
|
||||
for testName, test := range tests {
|
||||
t.Run(testName, func(t *testing.T) {
|
||||
th := kusttest_test.MakeHarness(t)
|
||||
for _, f := range test.input {
|
||||
f(th)
|
||||
}
|
||||
m := th.Run(".", th.MakeDefaultOptions())
|
||||
th.AssertActualEqualsExpected(m, test.expectedOutput)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ package krusty_test
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
|
||||
)
|
||||
|
||||
@@ -229,6 +228,9 @@ type: Opaque
|
||||
`)
|
||||
}
|
||||
|
||||
// TODO: This should be an error instead. However, we can't strict unmarshal until we have a yaml
|
||||
// lib that support case-insensitive keys and anchors.
|
||||
// See https://github.com/kubernetes-sigs/kustomize/issues/5061
|
||||
func TestGeneratorRepeatsInKustomization(t *testing.T) {
|
||||
th := kusttest_test.MakeHarness(t)
|
||||
th.WriteK(".", `
|
||||
@@ -261,13 +263,24 @@ krypton
|
||||
xenon
|
||||
radon
|
||||
`)
|
||||
err := th.RunWithErr(".", th.MakeDefaultOptions())
|
||||
if err == nil {
|
||||
t.Fatalf("expected an error")
|
||||
}
|
||||
assert.Contains(t, err.Error(),
|
||||
"invalid Kustomization: error converting YAML to JSON: yaml: unmarshal errors:\n"+
|
||||
" line 13: key \"literals\" already set in map\n line 18: key \"files\" already set in map")
|
||||
m := th.Run(".", th.MakeDefaultOptions())
|
||||
th.AssertActualEqualsExpected(m, `
|
||||
apiVersion: v1
|
||||
data:
|
||||
fruit: apple
|
||||
nobles: |2
|
||||
|
||||
helium
|
||||
neon
|
||||
argon
|
||||
krypton
|
||||
xenon
|
||||
radon
|
||||
vegetable: broccoli
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: blah-bob-db529cg5bk
|
||||
`)
|
||||
}
|
||||
|
||||
func TestIssue3393(t *testing.T) {
|
||||
@@ -558,3 +571,23 @@ metadata:
|
||||
name: test-k9cc55dfm5
|
||||
`)
|
||||
}
|
||||
|
||||
func TestDataIsSingleQuote(t *testing.T) {
|
||||
th := kusttest_test.MakeHarness(t)
|
||||
th.WriteK(".", `
|
||||
configMapGenerator:
|
||||
- name: test
|
||||
literals:
|
||||
- TEST='
|
||||
`)
|
||||
|
||||
m := th.Run(".", th.MakeDefaultOptions())
|
||||
th.AssertActualEqualsExpected(
|
||||
m, `apiVersion: v1
|
||||
data:
|
||||
TEST: ''''
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: test-m8t7bmb6g2
|
||||
`)
|
||||
}
|
||||
|
||||
@@ -9,9 +9,20 @@ import (
|
||||
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
|
||||
)
|
||||
|
||||
const expectedResources = `apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: myService
|
||||
spec:
|
||||
ports:
|
||||
- port: 7002
|
||||
`
|
||||
|
||||
func TestIssue596AllowDirectoriesThatAreSubstringsOfEachOther(t *testing.T) {
|
||||
th := kusttest_test.MakeHarness(t)
|
||||
th.WriteK("base", "")
|
||||
th.WriteF("base/service.yaml", expectedResources)
|
||||
th.WriteK("base", `resources:
|
||||
- service.yaml`)
|
||||
th.WriteK("overlays/aws", `
|
||||
resources:
|
||||
- ../../base
|
||||
@@ -25,5 +36,5 @@ resources:
|
||||
- ../aws-nonprod
|
||||
`)
|
||||
m := th.Run("overlays/aws-sandbox2.us-east-1", th.MakeDefaultOptions())
|
||||
th.AssertActualEqualsExpected(m, "")
|
||||
th.AssertActualEqualsExpected(m, expectedResources)
|
||||
}
|
||||
|
||||
@@ -504,313 +504,109 @@ func skipIfNoDocker(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestFnContainerGenerator(t *testing.T) {
|
||||
t.Skip("wait for #3881")
|
||||
skipIfNoDocker(t)
|
||||
|
||||
// Function plugins should not need the env setup done by MakeEnhancedHarness
|
||||
th := kusttest_test.MakeHarness(t)
|
||||
|
||||
th.WriteK(".", `
|
||||
o := th.MakeOptionsPluginsEnabled()
|
||||
tmpDir, err := filesys.NewTmpConfirmedDir()
|
||||
assert.NoError(t, err)
|
||||
th.WriteK(tmpDir.String(), `
|
||||
resources:
|
||||
- short_secret.yaml
|
||||
- deployment.yaml
|
||||
generators:
|
||||
- gener.yaml
|
||||
- project-service-set.yaml
|
||||
`)
|
||||
// Create generator config
|
||||
th.WriteF("gener.yaml", `
|
||||
apiVersion: examples.config.kubernetes.io/v1beta1
|
||||
kind: CockroachDB
|
||||
th.WriteF(filepath.Join(tmpDir.String(), "project-service-set.yaml"), `
|
||||
apiVersion: blueprints.cloud.google.com/v1alpha1
|
||||
kind: ProjectServiceSet
|
||||
metadata:
|
||||
name: demo
|
||||
annotations:
|
||||
config.kubernetes.io/function: |
|
||||
container:
|
||||
image: gcr.io/kustomize-functions/example-cockroachdb:v0.1.0
|
||||
image: gcr.io/kpt-fn/enable-gcp-services:v0.1.0
|
||||
spec:
|
||||
replicas: 3
|
||||
services:
|
||||
- compute.googleapis.com
|
||||
projectID: foo
|
||||
`)
|
||||
// Create some additional resource just to make sure everything is added
|
||||
th.WriteF("short_secret.yaml", `
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
// Create another resource just to make sure everything is added
|
||||
th.WriteF(filepath.Join(tmpDir.String(), "deployment.yaml"), `
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
labels:
|
||||
airshipit.org/ephemeral-user-data: "true"
|
||||
name: node1-bmc-secret
|
||||
type: Opaque
|
||||
stringData:
|
||||
userData: |
|
||||
bootcmd:
|
||||
- mkdir /mnt/vda
|
||||
name: foo
|
||||
`)
|
||||
m := th.Run(".", th.MakeOptionsPluginsEnabled())
|
||||
th.AssertActualEqualsExpected(m, `
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
m := th.Run(tmpDir.String(), o)
|
||||
actual, err := m.AsYaml()
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, `apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
labels:
|
||||
airshipit.org/ephemeral-user-data: "true"
|
||||
name: node1-bmc-secret
|
||||
stringData:
|
||||
userData: |
|
||||
bootcmd:
|
||||
- mkdir /mnt/vda
|
||||
type: Opaque
|
||||
name: foo
|
||||
---
|
||||
apiVersion: policy/v1beta1
|
||||
kind: PodDisruptionBudget
|
||||
metadata:
|
||||
labels:
|
||||
app: cockroachdb
|
||||
name: demo
|
||||
name: demo-budget
|
||||
spec:
|
||||
minAvailable: 67%
|
||||
selector:
|
||||
matchLabels:
|
||||
app: cockroachdb
|
||||
name: demo
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
labels:
|
||||
app: cockroachdb
|
||||
name: demo
|
||||
name: demo-public
|
||||
spec:
|
||||
ports:
|
||||
- name: grpc
|
||||
port: 26257
|
||||
targetPort: 26257
|
||||
- name: http
|
||||
port: 8080
|
||||
targetPort: 8080
|
||||
selector:
|
||||
app: cockroachdb
|
||||
name: demo
|
||||
---
|
||||
apiVersion: v1
|
||||
apiVersion: serviceusage.cnrm.cloud.google.com/v1beta1
|
||||
kind: Service
|
||||
metadata:
|
||||
annotations:
|
||||
prometheus.io/path: _status/vars
|
||||
prometheus.io/port: "8080"
|
||||
prometheus.io/scrape: "true"
|
||||
service.alpha.kubernetes.io/tolerate-unready-endpoints: "true"
|
||||
labels:
|
||||
app: cockroachdb
|
||||
name: demo
|
||||
name: demo
|
||||
blueprints.cloud.google.com/ownerReference: blueprints.cloud.google.com/ProjectServiceSet/demo
|
||||
config.kubernetes.io/function: |
|
||||
container:
|
||||
image: gcr.io/kpt-fn/enable-gcp-services:v0.1.0
|
||||
name: demo-compute
|
||||
spec:
|
||||
clusterIP: None
|
||||
ports:
|
||||
- name: grpc
|
||||
port: 26257
|
||||
targetPort: 26257
|
||||
- name: http
|
||||
port: 8080
|
||||
targetPort: 8080
|
||||
selector:
|
||||
app: cockroachdb
|
||||
name: demo
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: StatefulSet
|
||||
metadata:
|
||||
labels:
|
||||
app: cockroachdb
|
||||
name: demo
|
||||
name: demo
|
||||
spec:
|
||||
replicas: 3
|
||||
selector:
|
||||
matchLabels:
|
||||
app: cockroachdb
|
||||
name: demo
|
||||
serviceName: demo
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: cockroachdb
|
||||
name: demo
|
||||
spec:
|
||||
affinity:
|
||||
podAntiAffinity:
|
||||
preferredDuringSchedulingIgnoredDuringExecution:
|
||||
- podAffinityTerm:
|
||||
labelSelector:
|
||||
matchExpressions:
|
||||
- key: app
|
||||
operator: In
|
||||
values:
|
||||
- cockroachdb
|
||||
topologyKey: kubernetes.io/hostname
|
||||
weight: 100
|
||||
containers:
|
||||
- command:
|
||||
- /bin/bash
|
||||
- -ecx
|
||||
- |
|
||||
# The use of qualified `+"`hostname -f`"+` is crucial:
|
||||
# Other nodes aren't able to look up the unqualified hostname.
|
||||
CRARGS=("start" "--logtostderr" "--insecure" "--host" "$(hostname -f)" "--http-host" "0.0.0.0")
|
||||
# We only want to initialize a new cluster (by omitting the join flag)
|
||||
# if we're sure that we're the first node (i.e. index 0) and that
|
||||
# there aren't any other nodes running as part of the cluster that
|
||||
# this is supposed to be a part of (which indicates that a cluster
|
||||
# already exists and we should make sure not to create a new one).
|
||||
# It's fine to run without --join on a restart if there aren't any
|
||||
# other nodes.
|
||||
if [ ! "$(hostname)" == "cockroachdb-0" ] || [ -e "/cockroach/cockroach-data/cluster_exists_marker" ]
|
||||
then
|
||||
# We don't join cockroachdb in order to avoid a node attempting
|
||||
# to join itself, which currently doesn't work
|
||||
# (https://github.com/cockroachdb/cockroach/issues/9625).
|
||||
CRARGS+=("--join" "cockroachdb-public")
|
||||
fi
|
||||
exec /cockroach/cockroach ${CRARGS[*]}
|
||||
image: cockroachdb/cockroach:v1.1.0
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: demo
|
||||
ports:
|
||||
- containerPort: 26257
|
||||
name: grpc
|
||||
- containerPort: 8080
|
||||
name: http
|
||||
volumeMounts:
|
||||
- mountPath: /cockroach/cockroach-data
|
||||
name: datadir
|
||||
initContainers:
|
||||
- args:
|
||||
- -on-start=/on-start.sh
|
||||
- -service=cockroachdb
|
||||
env:
|
||||
- name: POD_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
||||
image: cockroachdb/cockroach-k8s-init:0.1
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: bootstrap
|
||||
volumeMounts:
|
||||
- mountPath: /cockroach/cockroach-data
|
||||
name: datadir
|
||||
terminationGracePeriodSeconds: 60
|
||||
volumes:
|
||||
- name: datadir
|
||||
persistentVolumeClaim:
|
||||
claimName: datadir
|
||||
volumeClaimTemplates:
|
||||
- metadata:
|
||||
name: datadir
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
resources:
|
||||
requests:
|
||||
storage: 1Gi
|
||||
`)
|
||||
projectRef:
|
||||
external: foo
|
||||
resourceID: compute.googleapis.com
|
||||
`, string(actual))
|
||||
}
|
||||
|
||||
func TestFnContainerTransformer(t *testing.T) {
|
||||
t.Skip("wait for #3881")
|
||||
skipIfNoDocker(t)
|
||||
|
||||
// Function plugins should not need the env setup done by MakeEnhancedHarness
|
||||
th := kusttest_test.MakeHarness(t)
|
||||
|
||||
th.WriteK(".", `
|
||||
o := th.MakeOptionsPluginsEnabled()
|
||||
tmpDir, err := filesys.NewTmpConfirmedDir()
|
||||
assert.NoError(t, err)
|
||||
th.WriteK(tmpDir.String(), `
|
||||
resources:
|
||||
- data.yaml
|
||||
- deployment.yaml
|
||||
transformers:
|
||||
- transf1.yaml
|
||||
- transf2.yaml
|
||||
- e2econtainerconfig.yaml
|
||||
`)
|
||||
|
||||
th.WriteF("data.yaml", `
|
||||
th.WriteF(filepath.Join(tmpDir.String(), "deployment.yaml"), `
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: nginx
|
||||
labels:
|
||||
app: nginx
|
||||
annotations:
|
||||
tshirt-size: small # this injects the resource reservations
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: nginx
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: nginx
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx
|
||||
name: foo
|
||||
`)
|
||||
// This transformer should add resource reservations based on annotation in data.yaml
|
||||
// See https://github.com/kubernetes-sigs/kustomize/tree/master/functions/examples/injection-tshirt-sizes
|
||||
th.WriteF("transf1.yaml", `
|
||||
apiVersion: examples.config.kubernetes.io/v1beta1
|
||||
kind: Validator
|
||||
th.WriteF(filepath.Join(tmpDir.String(), "e2econtainerconfig.yaml"), `
|
||||
apiVersion: example.com/v1alpha1
|
||||
kind: Input
|
||||
metadata:
|
||||
name: valid
|
||||
annotations:
|
||||
config.kubernetes.io/function: |-
|
||||
container:
|
||||
image: gcr.io/kustomize-functions/example-tshirt:v0.2.0
|
||||
`)
|
||||
// This transformer will check resources without and won't do any changes
|
||||
// See https://github.com/kubernetes-sigs/kustomize/tree/master/functions/examples/validator-kubeval
|
||||
th.WriteF("transf2.yaml", `
|
||||
apiVersion: examples.config.kubernetes.io/v1beta1
|
||||
kind: Kubeval
|
||||
metadata:
|
||||
name: validate
|
||||
name: foo
|
||||
annotations:
|
||||
config.kubernetes.io/function: |
|
||||
container:
|
||||
image: gcr.io/kustomize-functions/example-validator-kubeval:v0.1.0
|
||||
spec:
|
||||
strict: true
|
||||
ignoreMissingSchemas: true
|
||||
|
||||
# TODO: Update this to use network/volumes features.
|
||||
# Relevant issues:
|
||||
# - https://github.com/kubernetes-sigs/kustomize/issues/1901
|
||||
# - https://github.com/kubernetes-sigs/kustomize/issues/1902
|
||||
kubernetesVersion: "1.16.0"
|
||||
schemaLocation: "file:///schemas"
|
||||
image: "gcr.io/kustomize-functions/e2econtainerconfig"
|
||||
`)
|
||||
m := th.Run(".", th.MakeOptionsPluginsEnabled())
|
||||
th.AssertActualEqualsExpected(m, `
|
||||
apiVersion: apps/v1
|
||||
build := exec.Command("docker", "build", ".",
|
||||
"-f", "./cmd/config/internal/commands/e2e/e2econtainerconfig/Dockerfile",
|
||||
"-t", "gcr.io/kustomize-functions/e2econtainerconfig",
|
||||
)
|
||||
build.Dir = "../../" // Repo root
|
||||
assert.NoError(t, build.Run())
|
||||
m := th.Run(tmpDir.String(), o)
|
||||
actual, err := m.AsYaml()
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, `apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
annotations:
|
||||
tshirt-size: small
|
||||
labels:
|
||||
app: nginx
|
||||
name: nginx
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: nginx
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: nginx
|
||||
spec:
|
||||
containers:
|
||||
- image: nginx
|
||||
name: nginx
|
||||
resources:
|
||||
requests:
|
||||
cpu: 200m
|
||||
memory: 50M
|
||||
`)
|
||||
a-bool-value: "false"
|
||||
a-int-value: "0"
|
||||
a-string-value: ""
|
||||
name: foo
|
||||
`, string(actual))
|
||||
}
|
||||
|
||||
func TestFnContainerTransformerWithConfig(t *testing.T) {
|
||||
|
||||
@@ -12,7 +12,8 @@ import (
|
||||
"sigs.k8s.io/kustomize/kyaml/copyutil"
|
||||
)
|
||||
|
||||
const expectedHelm = `
|
||||
const (
|
||||
expectedHelm = `
|
||||
apiVersion: v1
|
||||
data:
|
||||
rcon-password: Q0hBTkdFTUUh
|
||||
@@ -46,6 +47,98 @@ spec:
|
||||
type: ClusterIP
|
||||
`
|
||||
|
||||
expectedHelmExternalDNS = `
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/instance: test
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/name: external-dns
|
||||
helm.sh/chart: external-dns-6.19.2
|
||||
name: test-external-dns
|
||||
namespace: default
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/instance: test
|
||||
app.kubernetes.io/name: external-dns
|
||||
template:
|
||||
metadata:
|
||||
annotations: null
|
||||
labels:
|
||||
app.kubernetes.io/instance: test
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/name: external-dns
|
||||
helm.sh/chart: external-dns-6.19.2
|
||||
spec:
|
||||
affinity:
|
||||
nodeAffinity: null
|
||||
podAffinity: null
|
||||
podAntiAffinity:
|
||||
preferredDuringSchedulingIgnoredDuringExecution:
|
||||
- podAffinityTerm:
|
||||
labelSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/instance: test
|
||||
app.kubernetes.io/name: external-dns
|
||||
topologyKey: kubernetes.io/hostname
|
||||
weight: 1
|
||||
containers:
|
||||
- args:
|
||||
- --metrics-address=:7979
|
||||
- --log-level=info
|
||||
- --log-format=text
|
||||
- --policy=upsert-only
|
||||
- --provider=aws
|
||||
- --registry=txt
|
||||
- --interval=1m
|
||||
- --source=service
|
||||
- --source=ingress
|
||||
- --aws-api-retries=3
|
||||
- --aws-zone-type=
|
||||
- --aws-batch-change-size=1000
|
||||
env:
|
||||
- name: AWS_DEFAULT_REGION
|
||||
value: us-east-1
|
||||
envFrom: null
|
||||
image: docker.io/bitnami/external-dns:0.13.4-debian-11-r14
|
||||
imagePullPolicy: IfNotPresent
|
||||
livenessProbe:
|
||||
failureThreshold: 2
|
||||
httpGet:
|
||||
path: /healthz
|
||||
port: http
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 10
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 5
|
||||
name: external-dns
|
||||
ports:
|
||||
- containerPort: 7979
|
||||
name: http
|
||||
readinessProbe:
|
||||
failureThreshold: 6
|
||||
httpGet:
|
||||
path: /healthz
|
||||
port: http
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 10
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 5
|
||||
resources:
|
||||
limits: {}
|
||||
requests: {}
|
||||
volumeMounts: null
|
||||
securityContext:
|
||||
fsGroup: 1001
|
||||
runAsUser: 1001
|
||||
serviceAccountName: default
|
||||
volumes: null
|
||||
`
|
||||
)
|
||||
|
||||
func TestHelmChartInflationGeneratorOld(t *testing.T) {
|
||||
th := kusttest_test.MakeEnhancedHarnessWithTmpRoot(t)
|
||||
defer th.Reset()
|
||||
@@ -84,6 +177,64 @@ helmCharts:
|
||||
th.AssertActualEqualsExpected(m, expectedHelm)
|
||||
}
|
||||
|
||||
func TestHelmChartInflationGeneratorWithOciRepository(t *testing.T) {
|
||||
th := kusttest_test.MakeEnhancedHarnessWithTmpRoot(t)
|
||||
defer th.Reset()
|
||||
if err := th.ErrIfNoHelm(); err != nil {
|
||||
t.Skip("skipping: " + err.Error())
|
||||
}
|
||||
|
||||
th.WriteK(th.GetRoot(), `
|
||||
helmCharts:
|
||||
- name: external-dns
|
||||
repo: oci://registry-1.docker.io/bitnamicharts
|
||||
version: 6.19.2
|
||||
releaseName: test
|
||||
valuesInline:
|
||||
crd:
|
||||
create: false
|
||||
rbac:
|
||||
create: false
|
||||
serviceAccount:
|
||||
create: false
|
||||
service:
|
||||
enabled: false
|
||||
|
||||
`)
|
||||
|
||||
m := th.Run(th.GetRoot(), th.MakeOptionsPluginsEnabled())
|
||||
th.AssertActualEqualsExpected(m, expectedHelmExternalDNS)
|
||||
}
|
||||
|
||||
func TestHelmChartInflationGeneratorWithOciRepositoryWithAppendSlash(t *testing.T) {
|
||||
th := kusttest_test.MakeEnhancedHarnessWithTmpRoot(t)
|
||||
defer th.Reset()
|
||||
if err := th.ErrIfNoHelm(); err != nil {
|
||||
t.Skip("skipping: " + err.Error())
|
||||
}
|
||||
|
||||
th.WriteK(th.GetRoot(), `
|
||||
helmCharts:
|
||||
- name: external-dns
|
||||
repo: oci://registry-1.docker.io/bitnamicharts/
|
||||
version: 6.19.2
|
||||
releaseName: test
|
||||
valuesInline:
|
||||
crd:
|
||||
create: false
|
||||
rbac:
|
||||
create: false
|
||||
serviceAccount:
|
||||
create: false
|
||||
service:
|
||||
enabled: false
|
||||
|
||||
`)
|
||||
|
||||
m := th.Run(th.GetRoot(), th.MakeOptionsPluginsEnabled())
|
||||
th.AssertActualEqualsExpected(m, expectedHelmExternalDNS)
|
||||
}
|
||||
|
||||
// Last mile helm - show how kustomize puts helm charts into different
|
||||
// namespaces with different customizations.
|
||||
func TestHelmChartProdVsDev(t *testing.T) {
|
||||
|
||||
@@ -8,11 +8,11 @@ import (
|
||||
"log"
|
||||
|
||||
"sigs.k8s.io/kustomize/api/internal/builtins"
|
||||
fLdr "sigs.k8s.io/kustomize/api/internal/loader"
|
||||
pLdr "sigs.k8s.io/kustomize/api/internal/plugins/loader"
|
||||
"sigs.k8s.io/kustomize/api/internal/target"
|
||||
"sigs.k8s.io/kustomize/api/internal/utils"
|
||||
"sigs.k8s.io/kustomize/api/konfig"
|
||||
fLdr "sigs.k8s.io/kustomize/api/loader"
|
||||
"sigs.k8s.io/kustomize/api/provenance"
|
||||
"sigs.k8s.io/kustomize/api/provider"
|
||||
"sigs.k8s.io/kustomize/api/resmap"
|
||||
|
||||
@@ -6,8 +6,6 @@ package krusty_test
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
|
||||
)
|
||||
|
||||
@@ -303,20 +301,15 @@ patchesStrategicMerge:
|
||||
m = th.Run("overlay", th.MakeDefaultOptions())
|
||||
th.AssertActualEqualsExpected(m, expected)
|
||||
|
||||
// Technique 4: "patches:" field, one patch file. Fails.
|
||||
// Technique 4: "patches:" field, one patch file.
|
||||
th.WriteK("overlay", `
|
||||
resources:
|
||||
- ../base
|
||||
patches:
|
||||
- path: twoPatchesInOneFile.yaml
|
||||
`)
|
||||
err := th.RunWithErr("overlay", th.MakeDefaultOptions())
|
||||
assert.Error(t, err)
|
||||
// This should fail, because the semantics of the `patches` field.
|
||||
// That field allows specific patch targeting to a list of targets,
|
||||
// while the `patchesStrategicMerge` field accepts patches that
|
||||
// implicitly identify their targets via GVKN.
|
||||
assert.Contains(t, err.Error(), "unable to parse SM or JSON patch from ")
|
||||
m = th.Run("overlay", th.MakeDefaultOptions())
|
||||
th.AssertActualEqualsExpected(m, expected)
|
||||
}
|
||||
|
||||
func TestRemoveEmptyDirWithNullFieldInSmp(t *testing.T) {
|
||||
@@ -1670,7 +1663,7 @@ spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- image: fluentd:latest
|
||||
- image: fluentd:latest
|
||||
name: fluentd
|
||||
serviceAccountName: fluentd-sa
|
||||
---
|
||||
|
||||
@@ -42,7 +42,7 @@ spec:
|
||||
serviceAccountName: mySvcAcct
|
||||
containers:
|
||||
- name: whatever
|
||||
image: k8s.gcr.io/governmentCheese
|
||||
image: registry.k8s.io/governmentCheese
|
||||
`)
|
||||
th.WriteF("base/serviceAccount.yaml", `
|
||||
apiVersion: v1
|
||||
@@ -61,7 +61,7 @@ spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- image: k8s.gcr.io/governmentCheese
|
||||
- image: registry.k8s.io/governmentCheese
|
||||
name: whatever
|
||||
serviceAccountName: mySvcAcct
|
||||
---
|
||||
@@ -80,7 +80,7 @@ spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- image: k8s.gcr.io/governmentCheese
|
||||
- image: registry.k8s.io/governmentCheese
|
||||
name: whatever
|
||||
serviceAccountName: mySvcAcct-private
|
||||
---
|
||||
@@ -115,7 +115,7 @@ commonLabels:
|
||||
app: external-dns
|
||||
instance: public
|
||||
images:
|
||||
- name: k8s.gcr.io/external-dns/external-dns
|
||||
- name: registry.k8s.io/external-dns/external-dns
|
||||
newName: xxx.azurecr.io/external-dns
|
||||
newTag: v0.7.4_sylr.1
|
||||
- name: quay.io/sylr/external-dns
|
||||
@@ -153,7 +153,7 @@ commonLabels:
|
||||
app: external-dns
|
||||
instance: private
|
||||
images:
|
||||
- name: k8s.gcr.io/external-dns/external-dns
|
||||
- name: registry.k8s.io/external-dns/external-dns
|
||||
newName: xxx.azurecr.io/external-dns
|
||||
newTag: v0.7.4_sylr.1
|
||||
- name: quay.io/sylr/external-dns
|
||||
@@ -192,7 +192,7 @@ commonLabels:
|
||||
app: external-dns
|
||||
instance: public
|
||||
images:
|
||||
- name: k8s.gcr.io/external-dns/external-dns
|
||||
- name: registry.k8s.io/external-dns/external-dns
|
||||
newName: quay.io/sylr/external-dns
|
||||
newTag: v0.7.4-73-g00a9a0c7
|
||||
secretGenerator:
|
||||
@@ -243,7 +243,7 @@ spec:
|
||||
serviceAccountName: external-dns
|
||||
containers:
|
||||
- name: external-dns
|
||||
image: k8s.gcr.io/external-dns/external-dns
|
||||
image: registry.k8s.io/external-dns/external-dns
|
||||
args:
|
||||
- --domain-filter=""
|
||||
- --txt-owner-id=""
|
||||
|
||||
@@ -801,3 +801,31 @@ metadata:
|
||||
namespace: iter8-monitoring
|
||||
`)
|
||||
}
|
||||
|
||||
// Demonstrates that metadata.name is only overridden for a kind: Namespace with apiVersion: v1
|
||||
// Test for issue #5072
|
||||
func TestNameNotOveriddenForNonCoreApiVersionOnANamespaceKind(t *testing.T) {
|
||||
th := kusttest_test.MakeHarness(t)
|
||||
|
||||
th.WriteF("azure-servicebus.yaml", `
|
||||
apiVersion: servicebus.azure.com/v1beta20210101preview
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: core-sb-99
|
||||
namespace: without-podinfo
|
||||
`)
|
||||
th.WriteK(".", `
|
||||
namespace: podinfo
|
||||
resources:
|
||||
- azure-servicebus.yaml
|
||||
`)
|
||||
|
||||
m := th.Run(".", th.MakeDefaultOptions())
|
||||
th.AssertActualEqualsExpected(m, `
|
||||
apiVersion: servicebus.azure.com/v1beta20210101preview
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: core-sb-99
|
||||
namespace: podinfo
|
||||
`)
|
||||
}
|
||||
|
||||
@@ -16,10 +16,10 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"sigs.k8s.io/kustomize/api/internal/loader"
|
||||
"sigs.k8s.io/kustomize/api/krusty"
|
||||
"sigs.k8s.io/kustomize/api/loader"
|
||||
"sigs.k8s.io/kustomize/api/resmap"
|
||||
"sigs.k8s.io/kustomize/kyaml/filesys"
|
||||
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
|
||||
"sigs.k8s.io/kustomize/kyaml/yaml"
|
||||
)
|
||||
|
||||
@@ -28,6 +28,7 @@ func TestRemoteLoad_LocalProtocol(t *testing.T) {
|
||||
root string
|
||||
simple string
|
||||
noSuffix string
|
||||
hash string
|
||||
multiBaseDev string
|
||||
withSubmodule string
|
||||
}
|
||||
@@ -36,9 +37,10 @@ func TestRemoteLoad_LocalProtocol(t *testing.T) {
|
||||
// root/
|
||||
// simple.git/ - base with just a pod
|
||||
// nosuffix/ - same as simple.git/ without the .git suffix
|
||||
// hash-xx/ - same as simple.git/ with random hash at xx
|
||||
// multibase.git/ - base with a dev overlay
|
||||
// with-submodule.git/ - includes `simple` as a submodule
|
||||
// submodule/ - the submodule referencing `simple
|
||||
// submodule/ - the submodule referencing `simple`
|
||||
createGitRepos := func(t *testing.T) testRepos {
|
||||
t.Helper()
|
||||
|
||||
@@ -50,10 +52,16 @@ func TestRemoteLoad_LocalProtocol(t *testing.T) {
|
||||
}
|
||||
}
|
||||
root := t.TempDir()
|
||||
|
||||
hashPath, err := os.MkdirTemp(root, "hash-")
|
||||
require.NoError(t, err)
|
||||
hashDir := filepath.Base(hashPath)
|
||||
|
||||
bash(fmt.Sprintf(`
|
||||
set -eux
|
||||
|
||||
export ROOT="%s"
|
||||
export HASH_DIR="%s"
|
||||
export GIT_AUTHOR_EMAIL=nobody@kustomize.io
|
||||
export GIT_AUTHOR_NAME=Nobody
|
||||
export GIT_COMMITTER_EMAIL=nobody@kustomize.io
|
||||
@@ -85,19 +93,27 @@ cp -r testdata/remoteload/multibase $ROOT/multibase.git
|
||||
git add .
|
||||
git commit -m "import"
|
||||
)
|
||||
cp -r testdata/remoteload/with-submodule $ROOT/with-submodule.git # see README
|
||||
cp -r $ROOT/simple.git/. $ROOT/$HASH_DIR
|
||||
(
|
||||
mkdir $ROOT/with-submodule.git
|
||||
cd $ROOT/with-submodule.git
|
||||
git init --initial-branch=main
|
||||
git submodule add $ROOT/simple.git submodule
|
||||
git add .
|
||||
git commit -m "import"
|
||||
git checkout -b relative-submodule
|
||||
git submodule add ../$HASH_DIR submodule
|
||||
git commit -m "relative submodule"
|
||||
git checkout main
|
||||
git submodule add $ROOT/simple.git submodule
|
||||
git commit -m "submodule"
|
||||
)
|
||||
`, root))
|
||||
`, root, hashDir))
|
||||
return testRepos{
|
||||
root: root,
|
||||
// The strings below aren't currently used, and more serve as documentation.
|
||||
simple: "simple.git",
|
||||
noSuffix: "nosuffix",
|
||||
hash: hashDir,
|
||||
multiBaseDev: "multibase.git",
|
||||
withSubmodule: "with-submodule.git",
|
||||
}
|
||||
@@ -183,6 +199,15 @@ resources:
|
||||
`,
|
||||
expected: simpleBuild,
|
||||
},
|
||||
{
|
||||
name: "has relative submodule",
|
||||
kustomization: `
|
||||
resources:
|
||||
- file://$ROOT/with-submodule.git/submodule?ref=relative-submodule
|
||||
`,
|
||||
|
||||
expected: simpleBuild,
|
||||
},
|
||||
{
|
||||
name: "has timeout",
|
||||
kustomization: `
|
||||
@@ -264,7 +289,7 @@ resources:
|
||||
}
|
||||
|
||||
kust := strings.ReplaceAll(test.kustomization, "$ROOT", repos.root)
|
||||
fSys, tmpDir := createKustDir(t, kust)
|
||||
fSys, tmpDir := kusttest_test.CreateKustDir(t, kust)
|
||||
|
||||
b := krusty.MakeKustomizer(krusty.MakeDefaultOptions())
|
||||
m, err := b.Run(
|
||||
@@ -273,7 +298,7 @@ resources:
|
||||
|
||||
if test.err != "" {
|
||||
require.Error(t, err)
|
||||
require.Contains(t, err.Error(), test.err)
|
||||
require.Regexp(t, test.err, err.Error())
|
||||
} else {
|
||||
require.NoError(t, err)
|
||||
checkYaml(t, m, strings.ReplaceAll(test.expected, "$ROOT", repos.root))
|
||||
@@ -368,7 +393,7 @@ resources:
|
||||
if test.beforeTest != nil {
|
||||
test.beforeTest(t)
|
||||
}
|
||||
fSys, tmpDir := createKustDir(t, test.kustomization)
|
||||
fSys, tmpDir := kusttest_test.CreateKustDir(t, test.kustomization)
|
||||
|
||||
b := krusty.MakeKustomizer(krusty.MakeDefaultOptions())
|
||||
m, err := b.Run(
|
||||
@@ -424,16 +449,6 @@ func configureGitSSHCommand(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func createKustDir(t *testing.T, content string) (filesys.FileSystem, filesys.ConfirmedDir) {
|
||||
t.Helper()
|
||||
|
||||
fSys := filesys.MakeFsOnDisk()
|
||||
tmpDir, err := filesys.NewTmpConfirmedDir()
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, fSys.WriteFile(filepath.Join(tmpDir.String(), "kustomization.yaml"), []byte(content)))
|
||||
return fSys, tmpDir
|
||||
}
|
||||
|
||||
func checkYaml(t *testing.T, actual resmap.ResMap, expected string) {
|
||||
t.Helper()
|
||||
|
||||
|
||||
@@ -546,3 +546,71 @@ metadata:
|
||||
name: red-dc6gc5btkc
|
||||
`)
|
||||
}
|
||||
|
||||
func TestReplacementTransformerWithSuffixTransformerAndReject(t *testing.T) {
|
||||
th := kusttest_test.MakeEnhancedHarness(t)
|
||||
defer th.Reset()
|
||||
|
||||
th.WriteF("base/app.yaml", `
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: original-name
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- image: app1:1.0
|
||||
name: app
|
||||
`)
|
||||
th.WriteK("base", `
|
||||
resources:
|
||||
- app.yaml
|
||||
`)
|
||||
th.WriteK("overlay", `
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
|
||||
nameSuffix: -dev
|
||||
resources:
|
||||
- ../base
|
||||
|
||||
configMapGenerator:
|
||||
- name: app-config
|
||||
literals:
|
||||
- name=something-else
|
||||
|
||||
replacements:
|
||||
- source:
|
||||
kind: ConfigMap
|
||||
name: app-config
|
||||
fieldPath: data.name
|
||||
targets:
|
||||
- fieldPaths:
|
||||
- spec.template.spec.containers.0.name
|
||||
select:
|
||||
kind: Deployment
|
||||
reject:
|
||||
- name: original-name
|
||||
`)
|
||||
m := th.Run("overlay", th.MakeDefaultOptions())
|
||||
th.AssertActualEqualsExpected(m, `
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: original-name-dev
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- image: app1:1.0
|
||||
name: app
|
||||
---
|
||||
apiVersion: v1
|
||||
data:
|
||||
name: something-else
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: app-config-dev-97544dk6t8
|
||||
`)
|
||||
}
|
||||
|
||||
10
api/krusty/testdata/remoteload/with-submodule/README.md
vendored
Normal file
10
api/krusty/testdata/remoteload/with-submodule/README.md
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
# submodule
|
||||
|
||||
This repo demonstrates kustomize's ability to download git repos
|
||||
with submodules. The following branches contain
|
||||
* main: submodule via absolute path
|
||||
* relative-submodule: submodule via relative path
|
||||
|
||||
For the submodule accessed via a relative path, we include a random hash in the
|
||||
submodule name to avoid accessing an unintended directory in the case kustomize
|
||||
contains loader bugs (issue #5131).
|
||||
@@ -37,7 +37,7 @@ spec:
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: k8s.gcr.io/nginx-slim:0.8
|
||||
image: registry.k8s.io/nginx-slim:0.8
|
||||
ports:
|
||||
- containerPort: 80
|
||||
name: web
|
||||
@@ -62,7 +62,7 @@ spec:
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: k8s.gcr.io/nginx-slim:0.8
|
||||
image: registry.k8s.io/nginx-slim:0.8
|
||||
ports:
|
||||
- containerPort: 80
|
||||
name: web
|
||||
@@ -116,7 +116,7 @@ spec:
|
||||
notIn: arrays
|
||||
spec:
|
||||
containers:
|
||||
- image: k8s.gcr.io/nginx-slim:0.8
|
||||
- image: registry.k8s.io/nginx-slim:0.8
|
||||
name: nginx
|
||||
ports:
|
||||
- containerPort: 80
|
||||
@@ -142,7 +142,7 @@ spec:
|
||||
notIn: arrays
|
||||
spec:
|
||||
containers:
|
||||
- image: k8s.gcr.io/nginx-slim:0.8
|
||||
- image: registry.k8s.io/nginx-slim:0.8
|
||||
name: nginx
|
||||
ports:
|
||||
- containerPort: 80
|
||||
|
||||
@@ -1848,7 +1848,7 @@ spec:
|
||||
terminationGracePeriodSeconds: 10
|
||||
containers:
|
||||
- name: nginx
|
||||
image: k8s.gcr.io/nginx-slim:0.8
|
||||
image: registry.k8s.io/nginx-slim:0.8
|
||||
ports:
|
||||
- containerPort: 80
|
||||
name: web
|
||||
@@ -2123,7 +2123,7 @@ spec:
|
||||
app: nginx
|
||||
spec:
|
||||
containers:
|
||||
- image: k8s.gcr.io/nginx-slim:0.8
|
||||
- image: registry.k8s.io/nginx-slim:0.8
|
||||
name: nginx
|
||||
ports:
|
||||
- containerPort: 80
|
||||
|
||||
@@ -187,7 +187,7 @@ func parseLiteralSource(source string) (keyName, value string, err error) {
|
||||
// removeQuotes removes the surrounding quotes from the provided string only if it is surrounded on both sides
|
||||
// rather than blindly trimming all quotation marks on either side.
|
||||
func removeQuotes(str string) string {
|
||||
if len(str) == 0 || str[0] != str[len(str)-1] {
|
||||
if len(str) < 2 || str[0] != str[len(str)-1] {
|
||||
return str
|
||||
}
|
||||
if str[0] == '"' || str[0] == '\'' {
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
ldr "sigs.k8s.io/kustomize/api/loader"
|
||||
ldr "sigs.k8s.io/kustomize/api/pkg/loader"
|
||||
valtest_test "sigs.k8s.io/kustomize/api/testutils/valtest"
|
||||
"sigs.k8s.io/kustomize/api/types"
|
||||
"sigs.k8s.io/kustomize/kyaml/filesys"
|
||||
|
||||
24
api/pkg/loader/loader.go
Normal file
24
api/pkg/loader/loader.go
Normal file
@@ -0,0 +1,24 @@
|
||||
// Copyright 2023 The Kubernetes Authors.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Package pkg has all the helpers to interact with the api.
|
||||
package loader
|
||||
|
||||
import (
|
||||
"sigs.k8s.io/kustomize/api/internal/loader"
|
||||
"sigs.k8s.io/kustomize/kyaml/filesys"
|
||||
)
|
||||
|
||||
// NewFileLoaderAtCwd returns a loader that loads from PWD.
|
||||
// A convenience for kustomize edit commands.
|
||||
func NewFileLoaderAtCwd(fSys filesys.FileSystem) *loader.FileLoader {
|
||||
return loader.NewLoaderOrDie(
|
||||
loader.RestrictionRootOnly, fSys, filesys.SelfDir)
|
||||
}
|
||||
|
||||
// NewFileLoaderAtRoot returns a loader that loads from "/".
|
||||
// A convenience for tests.
|
||||
func NewFileLoaderAtRoot(fSys filesys.FileSystem) *loader.FileLoader {
|
||||
return loader.NewLoaderOrDie(
|
||||
loader.RestrictionRootOnly, fSys, filesys.Separator)
|
||||
}
|
||||
@@ -9,8 +9,9 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"sigs.k8s.io/kustomize/api/ifc"
|
||||
loader "sigs.k8s.io/kustomize/api/internal/loader"
|
||||
"sigs.k8s.io/kustomize/api/kv"
|
||||
"sigs.k8s.io/kustomize/api/loader"
|
||||
ldrpkg "sigs.k8s.io/kustomize/api/pkg/loader"
|
||||
. "sigs.k8s.io/kustomize/api/resmap"
|
||||
resmaptest_test "sigs.k8s.io/kustomize/api/testutils/resmaptest"
|
||||
valtest_test "sigs.k8s.io/kustomize/api/testutils/valtest"
|
||||
@@ -249,7 +250,7 @@ func TestNewResMapFromSecretArgs(t *testing.T) {
|
||||
|
||||
actual, err := rmF.NewResMapFromSecretArgs(
|
||||
kv.NewLoader(
|
||||
loader.NewFileLoaderAtRoot(fSys),
|
||||
ldrpkg.NewFileLoaderAtRoot(fSys),
|
||||
valtest_test.MakeFakeValidator()), secrets)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
|
||||
@@ -696,8 +696,7 @@ func (m *resWrangler) DeAnchor() (err error) {
|
||||
}
|
||||
|
||||
// ApplySmPatch applies the patch, and errors on Id collisions.
|
||||
func (m *resWrangler) ApplySmPatch(
|
||||
selectedSet *resource.IdSet, patch *resource.Resource) error {
|
||||
func (m *resWrangler) ApplySmPatch(selectedSet *resource.IdSet, patch *resource.Resource) error {
|
||||
var list []*resource.Resource
|
||||
for _, res := range m.rList {
|
||||
if selectedSet.Contains(res.CurId()) {
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"sigs.k8s.io/kustomize/api/loader"
|
||||
"sigs.k8s.io/kustomize/api/internal/loader"
|
||||
. "sigs.k8s.io/kustomize/api/resource"
|
||||
"sigs.k8s.io/kustomize/api/types"
|
||||
"sigs.k8s.io/kustomize/kyaml/filesys"
|
||||
|
||||
@@ -7,8 +7,8 @@ import (
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"sigs.k8s.io/kustomize/api/internal/konfig/builtinpluginconsts"
|
||||
"sigs.k8s.io/kustomize/api/konfig"
|
||||
"sigs.k8s.io/kustomize/api/konfig/builtinpluginconsts"
|
||||
"sigs.k8s.io/kustomize/api/krusty"
|
||||
"sigs.k8s.io/kustomize/api/resmap"
|
||||
"sigs.k8s.io/kustomize/api/types"
|
||||
|
||||
@@ -11,9 +11,9 @@ import (
|
||||
"testing"
|
||||
|
||||
"sigs.k8s.io/kustomize/api/ifc"
|
||||
fLdr "sigs.k8s.io/kustomize/api/internal/loader"
|
||||
pLdr "sigs.k8s.io/kustomize/api/internal/plugins/loader"
|
||||
"sigs.k8s.io/kustomize/api/konfig"
|
||||
fLdr "sigs.k8s.io/kustomize/api/loader"
|
||||
"sigs.k8s.io/kustomize/api/provider"
|
||||
"sigs.k8s.io/kustomize/api/resmap"
|
||||
valtest_test "sigs.k8s.io/kustomize/api/testutils/valtest"
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user