Compare commits

...

611 Commits

Author SHA1 Message Date
Kubernetes Prow Robot
bb5022441a Merge pull request #5393 from koba1t/pinToKyaml
Update kyaml to v0.15.0
2023-10-19 18:59:14 +02:00
koba1t
8668b74622 Update kyaml to v0.15.0 2023-10-20 01:07:49 +09:00
Kubernetes Prow Robot
752bb2ef41 Merge pull request #5303 from antoooks/refactor/ci-tasks-improvement-new
refactor/ci tasks improvement new
2023-10-19 09:41:50 +02:00
Kubernetes Prow Robot
bde28b1320 Merge pull request #5324 from charles-chenzz/fix_doc_refs
update deprecated doc refs
2023-10-18 17:41:01 +02:00
Kubernetes Prow Robot
689dcefa3a Merge pull request #5378 from kubernetes-sigs/dependabot/go_modules/cmd/depprobcheck/golang.org/x/net-0.17.0
build(deps): bump golang.org/x/net from 0.8.0 to 0.17.0 in /cmd/depprobcheck
2023-10-18 16:05:15 +02:00
dependabot[bot]
f3e263a051 build(deps): bump golang.org/x/net in /cmd/depprobcheck
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.8.0 to 0.17.0.
- [Commits](https://github.com/golang/net/compare/v0.8.0...v0.17.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-18 13:27:09 +00:00
Kubernetes Prow Robot
fa48ab16bf Merge pull request #5377 from kubernetes-sigs/dependabot/go_modules/functions/examples/application-cr/image/golang.org/x/net-0.17.0
build(deps): bump golang.org/x/net from 0.8.0 to 0.17.0 in /functions/examples/application-cr/image
2023-10-18 15:25:21 +02:00
dependabot[bot]
0eca5c4b06 build(deps): bump golang.org/x/net
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.8.0 to 0.17.0.
- [Commits](https://github.com/golang/net/compare/v0.8.0...v0.17.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-17 19:51:16 +00:00
Kubernetes Prow Robot
6b76c807f5 Merge pull request #5376 from kubernetes-sigs/dependabot/go_modules/functions/examples/fn-framework-application/golang.org/x/net-0.17.0
build(deps): bump golang.org/x/net from 0.8.0 to 0.17.0 in /functions/examples/fn-framework-application
2023-10-17 21:48:54 +02:00
dependabot[bot]
76695414c7 build(deps): bump golang.org/x/net
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.8.0 to 0.17.0.
- [Commits](https://github.com/golang/net/compare/v0.8.0...v0.17.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-10-17 19:24:53 +00:00
Jan-Otto Kröpke
d64ac13447 kustomize: Add support for OCI based helm repos (#5167)
* kustomize: Add support for OCI based helm repos

Signed-off-by: Jan-Otto Kröpke <joe@cloudeteer.de>

* Update api/internal/builtins/HelmChartInflationGenerator.go

* Update plugin/builtin/helmchartinflationgenerator/HelmChartInflationGenerator.go

* go fmt

Signed-off-by: Jan-Otto Kröpke <joe@cloudeteer.de>

* s/expectedHelmExternalDns/expectedHelmExternalDNS

Signed-off-by: Jan-Otto Kröpke <joe@cloudeteer.de>

* commit

Signed-off-by: Jan-Otto Kröpke <joe@cloudeteer.de>

* commit with content

Signed-off-by: Jan-Otto Kröpke <joe@cloudeteer.de>

* Apply suggestions from maintainer

* go work sync

* added test

---------

Signed-off-by: Jan-Otto Kröpke <joe@cloudeteer.de>
2023-10-17 21:24:00 +02:00
Kubernetes Prow Robot
f80d9c41e5 Merge pull request #5370 from phooijenga/patch-1
merge2: fix duplicate test case
2023-10-14 18:41:37 +02:00
Kubernetes Prow Robot
2f99707792 Merge pull request #5367 from stormqueen1990/fix/edit-add-configmap-namespace
fix: add namespace option to 'edit add configmap' command
2023-10-14 09:39:40 +02:00
Mauren Berti
7a08dde7ac fix: change spaces for tabs 2023-10-13 18:35:27 -04:00
Kubernetes Prow Robot
81297df4ff Merge pull request #5374 from kundan2707/broken_link
Path for glossary.md corrected
2023-10-13 22:14:55 +02:00
Kundan Kumar
c4137c0c2a Path for glossary corrected 2023-10-12 10:29:05 +05:30
charles-chenzz
944c72a275 update deprecated doc refs 2023-10-11 22:30:43 +08:00
Paul
46e2d72213 merge2: fix duplicate test case 2023-10-10 14:12:07 +02:00
Mauren Berti
6cb85e8544 fix: remove unnecessary empty space as per lint 2023-10-09 19:28:37 -04:00
Mauren Berti
6ef9773c02 docs: update comment to reflect usage of namespace
Update the comment for the namespace option to reflect its real usage for both
secret and configmap.
2023-10-09 17:17:49 -04:00
Mauren Berti
11aa57e67f fix: add --namespace flag to edit add configmap
* Add the option to specify a namespace when using 'kustomize edit add configmap'
  for code parity with 'edit add secret'.
* Rename constants for 'add configmap'/'add secret' so they are standardized.
* Create new constant for the 'namespace' flag.
* Update test cases to cover new scenarios.
2023-10-09 17:17:40 -04:00
Kubernetes Prow Robot
779f153071 Merge pull request #5353 from charles-chenzz/git_submodule
git submodule need origin
2023-10-07 03:27:32 +02:00
charles-chenzz
60d7ee6710 add orgin back when clone repo (due to git submodule). 2023-10-07 07:50:13 +08:00
Kubernetes Prow Robot
852739c477 Merge pull request #5265 from rodrigc/update-remote-example
doc: update example to use tag v3.3.1
2023-10-06 21:21:37 +02:00
Craig Rodrigues
bee2e5f50c doc: update example to use tag v3.3.1
Signed-off-by: Craig Rodrigues <rodrigc@crodrigues.org>
2023-10-06 11:38:17 -07:00
Natasha Sarkar
ace2d53b18 Merge pull request #5333 from hailkomputer/add-skip-validation-flag-to-edit-add-resource
Add --no-verify flag to edit add resource command
2023-10-06 13:00:27 -05:00
Kubernetes Prow Robot
aeb7cb2a40 Merge pull request #5342 from superbrothers/fix-issue4905
Update imdario/mergo to v0.3.13
2023-10-04 22:06:34 +02:00
Yigit Demirbas
713842330e rename flag to --no-verify 2023-10-03 09:02:34 +02:00
Yigit Demirbas
5936a892a7 fix imports after rebase 2023-10-02 09:06:07 +02:00
Yigit Demirbas
c3a4f3eab6 Merge branch 'master' into add-skip-validation-flag-to-edit-add-resource 2023-10-02 09:03:14 +02:00
Mauren Berti
fb7ee2f487 refactor: change "add configmap/secret" commands to reuse code and improve tests (#5315)
* feat: minor refactoring + test improvements

* Refactor some bits of the edit add secret/configmap commands to reuse code.
* Improve test coverage for both these commands by invoking the cobra command
  directly.
* Add some reusable constants for both these commands and their tests.

* fix: changes from code review

* Update formatting as requested in code review.
* Rename flagsAndArgs to configmapSecretFlagsAndArgs: change the file and struct
  names to reflect the real usage of this code.
* Remove excessive newlines from the imports block.
* Replace all usages of assert with require and fix newlines in imports.
2023-10-01 19:32:45 -07:00
Kubernetes Prow Robot
45e57f0228 Merge pull request #5350 from kubernetes-sigs/revert-5332-master
Revert "Disable CI Code Checks if all PR changes fall under `site/`"
2023-09-29 15:01:56 -07:00
Kubernetes Prow Robot
9920586b22 Merge pull request #5345 from stormqueen1990/docs/update-remove-configmap-comment
docs: update remove configmap comment
2023-09-29 11:12:42 -07:00
Kubernetes Prow Robot
61dad14345 Merge pull request #5344 from stormqueen1990/feat/add-remove-secret-command
feat: add remove secret command
2023-09-29 11:02:43 -07:00
Kubernetes Prow Robot
f65506d285 Merge pull request #5268 from kubernetes-sigs/dependabot/github_actions/nashmaniac/create-issue-action-1.2
Bump nashmaniac/create-issue-action from 1.1 to 1.2
2023-09-29 10:52:43 -07:00
Natasha Sarkar
cbbd1599f2 Revert "Disable CI Code Checks if all PR changes fall under site/" 2023-09-29 09:50:39 -05:00
Kubernetes Prow Robot
4b34ff3075 Merge pull request #5132 from samstride/issue/5127
Update README.md
2023-09-28 12:10:34 -07:00
Kubernetes Prow Robot
654d7953d9 Merge pull request #5193 from varshaprasad96/refactor/api
[refactor]: Internalize loader api
2023-09-28 08:36:32 -07:00
Kurnianto Trilaksono
d91ea65f5a separate generate plugins and check diff step 2023-09-28 21:49:57 +07:00
Varsha Prasad Narsing
7911b2c001 [refactor]: Internalize loader api
This PR intends to move the loader api to
internal. Only the necessary methods which
are needed for the api have been put into
`pkg/loader.go`.

Signed-off-by: Varsha Prasad Narsing <varshaprasad96@gmail.com>
2023-09-28 10:49:45 -04:00
Yigit Demirbas
0d854a5144 modify error message to original 2023-09-27 12:52:09 +02:00
Yigit Demirbas
cb5b241715 modify add resource test to accomodate changes 2023-09-27 12:49:19 +02:00
Yigit Demirbas
039b05fb16 refactor tests to use require instead 2023-09-27 12:40:05 +02:00
Mauren Berti
9c1d412dac docs: update remove configmap comment
Update the comment for the newCmdRemoveConfigMap function to explain what this
function really does. The previous comment was referring to a different function.
2023-09-24 19:26:48 -04:00
Mauren Berti
a318d4db26 feat: incorporate feedback from review
* Incorporate feedback from reviews.
* Add extra test cases to increase coverage.
* Tiny refactors for code parity with remove configmap.
* Update copyright notice.
2023-09-24 19:16:37 -04:00
yufei.li
0cfafddacc feat: add remove secret command
(cherry picked from commit 63d44f5e88)

chore: fix for lint

(cherry picked from commit 21edcd0582)

fix: correct lint issues

(cherry picked from commit 0c87856b2c)

fix: Resolve conversations

(cherry picked from commit 9ee5ab3a70)
2023-09-24 18:07:55 -04:00
Kazuki Suda
f5ca753377 Update imdario/mergo to v0.3.13
Co-authored-by: Krzysztof Gibuła <krzysztof.gibula@gmail.com>
Signed-off-by: Kazuki Suda <kazuki.suda@gmail.com>
2023-09-24 16:34:45 +09:00
Kazuki Suda
0d4849ff98 Add a test case for issue 4905
```
===== ACTUAL BEGIN ========================================
apiVersion: v1
data:
  config.yaml: "null"
kind: ConfigMap
metadata:
  name: issue4905
===== ACTUAL END ==========================================
   EXPECTED              ACTUAL
   --------              ------
   apiVersion: v1        apiVersion: v1
   data:                 data:
X    config.yaml: |-       config.yaml: "null"
X      item1: 1          kind: ConfigMap
X      item2: 2          metadata:
X  kind: ConfigMap         name: issue4905
X  metadata:
X    name: issue4905
    hasgett.go:22: Expected not equal to actual
--- FAIL: TestHelmChartInflationGeneratorIssue4905 (0.24s)
```

Signed-off-by: Kazuki Suda <kazuki.suda@gmail.com>
2023-09-24 16:33:43 +09:00
Nick
e3b9afcfaa Add CLI page to Reference Section (#5304)
* Add CLI page

Start operations section

Refine operations section

Add common operations

Address comments

* Move the cli content to the CLI section

Update the CLI description
2023-09-22 23:30:56 -07:00
Kubernetes Prow Robot
af781bfa5e Merge pull request #5313 from bugoverdose/docs/api
Add API section to Reference Section
2023-09-22 22:56:55 -07:00
Kubernetes Prow Robot
7dd9637b1a Merge pull request #5340 from koba1t/add_koba1t_to_approvers
add koba1t to approvers
2023-09-22 13:48:49 -07:00
koba1t
ddce57b585 add koba1t to approvers 2023-09-23 03:37:24 +09:00
Natasha Sarkar
11fc419cee be more specific about reqs in contributing guide (#5330)
* be more specific about reqs in contributing guide

* fix wording
2023-09-22 11:14:48 -07:00
Kubernetes Prow Robot
a8dec66a84 Merge pull request #4486 from koba1t/feature/add_edit_set_labels_subcommand_add_option_for_labels_on_without_selector
add: "edit add labels" command adds an option for labels without selector
2023-09-22 09:36:50 -07:00
Kubernetes Prow Robot
7e541ca380 Merge pull request #5332 from roopeshvs/master
Disable CI Code Checks if all PR changes fall under `site/`
2023-09-20 14:46:02 -07:00
Kubernetes Prow Robot
1bd58bdc15 Merge pull request #5327 from stormqueen1990/feat/add-remove-configmap-command
feat: add remove configmap command
2023-09-20 14:32:01 -07:00
Mauren Berti
9107fa3c81 fix: changes from code review
* Replace last assert directive with require in the test.
* Change copyright notice.
2023-09-19 22:29:33 -04:00
Yigit Demirbas
df0cd3c4a3 modified to fix linter issues 2023-09-18 20:54:56 +02:00
Yigit Demirbas
f3b34c44b5 Add skip-validation flag to edit add resource cmd 2023-09-18 20:22:59 +02:00
Kurnianto Trilaksono
9e101ee97f use doGoMod.sh forr go mod tidy 2023-09-18 23:17:11 +07:00
Roopesh V S
433be59ea7 ignore pr code checks for docs only changes 2023-09-18 19:49:11 +05:30
Jeong Jinwoo
2c444d6bf4 docs(api/kustomizaion-file): migrate field sections 2023-09-17 16:05:32 +09:00
Kurnianto Trilaksono
a90c19d577 Edit commentaries and ensure pluginator logic does not create diff 2023-09-17 00:23:32 +07:00
Kurnianto Trilaksono
8f283499e9 add go mod tidy before workspace sync 2023-09-16 21:47:23 +07:00
Kurnianto Trilaksono
d78fe665a7 add commentaries, change command order on presubmit-check 2023-09-16 21:47:23 +07:00
Kurnianto Trilaksono
532abf77e7 refactor: fix generate-kustimize-builtin-plugins, add diff checker on generate-kustomize-builtin-plugins, add go work sync on presubmit check, add generate-kustomize-builtin-plugins on presubmit check 2023-09-16 21:47:23 +07:00
yugo kobayashi
59696d1ace fix a patch files accept multiple patches (#5194)
* fix a patch files accept multiple patches

* fix comments and variable name

* add error handling when using not allowed multiple strategic-merge patches

* fix error message of Multiple Strategic-Merge Patch file

* refactor transformStrategicMerge()

* add TODO comment and test for Multiple JSON patch Yaml documents are not allowed

* refactoring PatchTransformer

* add multiple patch test for PatchTransformer package

* improve error message to PatchTransformer

* refactor const and error message check

* fix some error messages
2023-09-15 16:20:13 -07:00
Jeong Jinwoo
d30e457031 docs(api/patches): fix broken links 2023-09-14 21:01:25 +09:00
Jeong Jinwoo
ae041b5c54 docs(api/generatorOptions): fill up empty links 2023-09-14 20:54:06 +09:00
Jeong Jinwoo
a2b60e4bcb docs(api): fix broken links 2023-09-14 20:52:11 +09:00
Jeong Jinwoo
9d126f6dd8 docs(api/components): add Components guide from cli-experimental
- add reference to Concept page
2023-09-14 12:55:50 +09:00
Jeong Jinwoo
bd8045b648 docs(api/replacements): fix heavy check mark issue 2023-09-14 12:40:57 +09:00
Jeong Jinwoo
5c1a022a3c docs(api): fix broken hyperlinks 2023-09-14 12:40:57 +09:00
Jeong Jinwoo
e19ca5405a docs: setup API section with cli-experimental site 2023-09-14 12:40:54 +09:00
Kubernetes Prow Robot
56d37acc7d Merge pull request #5261 from varshaprasad96/refactor/image
[Refactor] Move image to internal
2023-09-13 10:22:12 -07:00
Mauren Berti
0571a2f15d Incorporate feedback from original PR
* Incorporate feedback left on original PR.
* Add more test cases.
* Minor refactoring and update to copyright notice.
2023-09-12 20:18:45 -04:00
yufei.li
0cdfa5b3dc feat: add remove configmap command
(cherry picked from commit 0d7c56dcf8)

fix: add logging when configmap not exists

(cherry picked from commit 0235f10b09)

fix: correct lint issues

(cherry picked from commit 8ca1f3813b)

fix: Resolve conversation

(cherry picked from commit 927804dfe5)
2023-09-12 19:21:55 -04:00
Anna Song
7c36ed21b3 Document AnnotationsTransformer (#5247)
* Restructure existing Reference docs

Restructure Reference section for site to better match k8s.io. Change
descriptions to complete sentences. Improve instructions to locally load
site.

* Document AnnotationsTransformer on site

Dcoument AnnotationsTransformer API under Reference on site.

* Document required fields

Document required fields and explain effects of optional ones.

* Make site setup instructions more explicit

* Link required K8s fields
2023-09-08 20:54:10 -07:00
Ed Overton
985835f96f perf: limit initSchema calls from openapi.IsNamespaceScoped (#5076)
* test: add openapi.IsNamespaceScoped benchmark

Add a benchmark test for IsNamespaceScoped performance when the default
schema is in use.

* perf: limit initSchema calls from openapi.IsNamespaceScoped

Avoid calling initSchema from openapi.IsNamespaceScoped when possible.
Work done in #4152 introduced a precomputed namespace scope map based on
the default built-in schema. This commit extends that work by avoiding
calls to initSchema when a resource is not found in the precomputed map
and the default built-in schema is in use. In those cases, there is no
benefit to calling initSchema since the precomputed map is exactly what
will be calculated by parsing the default built-in schema.

* fix: delay parsing of default built-in schema

When namespace scope can be determined by the precomputed map but the
type is not present in the precomputed map, delay the parsing of the
default built-in schema.

If the schema to be initialized is the default built-in schema and the
type is not in the precomputed map, then the type will not be found in
the default built-in schema. There is no need to parse the default
built-in schema for that answer; its parsing may be delayed until it
is needed for some other purpose.

In cases where the schema is used solely for namespace scope checks, the
schema might not ever be parsed. Skipping the parsing reduces both
execution time and memory use.

* fix: correct openapi.go's schemaNotParsed value

openapiData initializes with defaultBuiltInSchemaParseStatus set to 0,
so schemaNotParsed should have 0 as its value.
2023-09-08 12:34:30 -07:00
Kubernetes Prow Robot
f81765b96e Merge pull request #5320 from natasha41575/updatedeps
small fixes
2023-09-08 10:06:14 -07:00
natasha41575
a2ceaff053 small fixes 2023-09-08 11:38:23 -05:00
Kubernetes Prow Robot
94181b1be7 Merge pull request #5291 from irvifa/refactor/remove-setters-config-from-kyaml
refactor: Remove setters from kyaml
2023-09-08 07:54:14 -07:00
Kubernetes Prow Robot
169fdd7330 Merge pull request #5196 from ephesused/issue4928-append-honors-key-style
fix: patch additions honor source key style
2023-09-01 09:06:33 -07:00
Ed Overton
78b8139d46 Merge branch 'master' into issue4928-append-honors-key-style 2023-08-30 12:30:49 -04:00
Kubernetes Prow Robot
76f8d2828b Merge pull request #5197 from skitt/json-patch.v5
Switch to json-patch v5
2023-08-28 09:35:45 -07:00
Stephen Kitt
b692e49b1e Switch to json-patch v5
json-patch was bumped to v5 in k/k as a result of
https://github.com/kubernetes/kubernetes/pull/118384; this aligns with
that, but switches to the v5 module, which is documented as
gopkg.in/evanphx/json-patch.v5.

Signed-off-by: Stephen Kitt <skitt@redhat.com>
2023-08-26 08:42:07 +02:00
Kubernetes Prow Robot
bd7f001c26 Merge pull request #5239 from koba1t/chore/change_release_flow
change release flow from using goreleaser to build scripts
2023-08-25 11:54:52 -07:00
Kubernetes Prow Robot
d6ff768298 Merge pull request #5262 from varshaprasad96/refactor/konfig
[Refactor] Internalize konfig constants
2023-08-25 10:18:52 -07:00
Irvi Aini
4947a905fa refactor: Remove setters from kyaml
Kind:

Refactor

Summary:

Setters functionality is provided as a KRM function. We should remove code related to setters in cmd/config and kyaml.
As of now most setters2 and setters usage are related to fork of kpt, however, these:
[fluxcd/image-automation-controller](6827808a1a/pkg/update/filter.go (L24)) with [kyml](6827808a1a/go.mod (L42))
[rancher/fleet](0a6cf6cb92/internal/cmd/controller/controllers/image/update/setters.go (L16)) with [kyaml](0a6cf6cb92/go.mod (L75))

Repositories still using them, They pinned these two into a specific kyaml version. If we decide to go for this removal then we can make a release note that this is actually removed on the next version since we already marked this as deprecated before.
2023-08-24 00:39:47 +08:00
Kubernetes Prow Robot
cd9a16cfab Merge pull request #5273 from natasha41575/pm
add description of PM role to contributing doc
2023-08-22 14:11:55 -07:00
natasha41575
02a53f193d add description of PM role to contributing doc 2023-08-22 15:11:53 -05:00
koba1t
b1717c8a97 change_release_flow_to_build_scripts 2023-08-17 22:57:44 +09:00
Kubernetes Prow Robot
911ddcda40 Merge pull request #5263 from bugoverdose/fix/reject-on-id-change
Fix `reject` needing both current and previous ids
2023-08-14 09:19:22 -07:00
dependabot[bot]
daf06622a2 Bump nashmaniac/create-issue-action from 1.1 to 1.2
Bumps [nashmaniac/create-issue-action](https://github.com/nashmaniac/create-issue-action) from 1.1 to 1.2.
- [Release notes](https://github.com/nashmaniac/create-issue-action/releases)
- [Commits](https://github.com/nashmaniac/create-issue-action/compare/v1.1...v1.2)

---
updated-dependencies:
- dependency-name: nashmaniac/create-issue-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-08-14 00:53:35 +00:00
Jeong Jinwoo
9f1d5acdc8 fix: check both prev and current ids for filtering reject targets 2023-08-11 21:37:55 +09:00
Jeong Jinwoo
9756d92a91 test: demonstrate reject not working on targets with changed id 2023-08-11 21:37:07 +09:00
Natasha Sarkar
d32d1937e6 Merge pull request #5254 from natasha41575/unpineverything
release cleanup
2023-08-10 12:03:25 -05:00
Varsha Prasad Narsing
ddcbae54ab [Refactor] Internalize konfig constants
This PR is an effort towards internalizing public APIs.
It moves some of the builtinconstants to internal/

Signed-off-by: Varsha Prasad Narsing <varshaprasad96@gmail.com>
2023-08-09 14:14:48 -04:00
Varsha Prasad Narsing
ca748faa3f [Refactor] Move image/ to internal
This PR is an effort towards reducing the public surface
of APIs. It move image/ to internal/image

Signed-off-by: Varsha Prasad Narsing <varshaprasad96@gmail.com>
(cherry picked from commit 1f5890709fdc17de6f44f42b5138dd0f7e64bc74)
2023-08-09 13:40:07 -04:00
Kubernetes Prow Robot
5e6cbac589 Merge pull request #5203 from varshaprasad96/add/goapi-diff
[Chore] Enable go-api-diff checker
2023-08-07 08:42:32 -07:00
natasha41575
ff75dd6cd5 release cleanup 2023-07-31 12:27:44 -05:00
Natasha Sarkar
f8391994b4 Merge pull request #5253 from natasha41575/pincmdconfigandapi
pin to cmd/config and api
2023-07-31 11:49:43 -05:00
natasha41575
5ce14e5024 pin to cmd/config and api 2023-07-31 11:28:25 -05:00
Natasha Sarkar
ee22c9cab7 Merge pull request #5252 from natasha41575/pinkyaml
pin to kyaml 0.14.3
2023-07-31 11:24:02 -05:00
natasha41575
4a893ce8c6 pin to kyaml 2023-07-31 11:08:00 -05:00
Kubernetes Prow Robot
9ce923ebeb Merge pull request #5245 from yedayak/customization-typo
Fix typo in help for the create subcommand
2023-07-25 12:47:57 -07:00
Yedaya
494a807f28 Fix typo in help for the create subcommand 2023-07-18 09:58:14 +03:00
Varsha Prasad Narsing
820f17c73b [Chore] Enable go-api-diff checker
This PR introduces go-api-diff checker in Makefile
and in CI to make sure we don't end up breaking APIs
unintentionally.

Signed-off-by: Varsha Prasad Narsing <varshaprasad96@gmail.com>
2023-07-12 13:55:07 -04:00
Kubernetes Prow Robot
cd7ba1744e Merge pull request #5189 from annasong20/test-relative-submodules
Add test for issue #5131
2023-07-12 10:03:13 -07:00
Anna Song
da4e881007 Add accumulateResources error tests for local files (#5225)
* Add accumulateResources error tests for local files.

Add tests demonstrating accumulateResources errors when the resource is
a local file. Works to address #4807.

* Improve readability
2023-07-01 11:46:49 -07:00
Natasha Sarkar
878cda7c55 Merge pull request #5215 from natasha41575/unpin
release cleanup
2023-06-19 12:23:20 -05:00
natasha41575
47327616df update latest release version 2023-06-19 12:06:16 -05:00
natasha41575
eeff67d88d unpin everything 2023-06-19 12:05:59 -05:00
Natasha Sarkar
6adf4f294a Merge pull request #5214 from natasha41575/pintoapi
pin to api
2023-06-19 11:53:36 -05:00
natasha41575
5e7cc3437d pintoapi 2023-06-19 11:35:33 -05:00
Natasha Sarkar
ded76df3af Merge pull request #5213 from natasha41575/pintocmdconfig
pin to cmd/config
2023-06-19 11:24:40 -05:00
natasha41575
d7362ed22d pin to cmd/config 2023-06-19 11:07:36 -05:00
Natasha Sarkar
4711bfe40c Merge pull request #5212 from natasha41575/pintokyaml
pin to kyaml
2023-06-19 11:02:27 -05:00
natasha41575
8c0e0b3b47 pin to kyaml 2023-06-19 10:45:18 -05:00
Ed Overton
096b2c4435 test: add psm test for different key types 2023-06-15 16:12:29 -04:00
Anna Song
129d0f90af Add test for issue #5131 2023-06-14 18:32:12 +00:00
Ed Overton
c76fd5eb85 test: update psm key style test 2023-06-13 14:50:22 -04:00
Kubernetes Prow Robot
9e42f8d57e Merge pull request #5177 from annasong20/test-accumulate-remote-file
Test accumulateResources errors for remote files
2023-06-13 07:33:59 -07:00
Anna Song
168e31bfb6 Add accumulateResources remote file error tests
Test accumulateResources errors when a remote file fails to load. This
is part of the effort to fix issue #4807.
2023-06-09 21:31:27 +00:00
Ed Overton
691b7d1df3 fix: patch additions honor source key style
When a patch appends a new node, it should honor the key style from the
patch. Prior to this commit, no style was applied, leading to problems
when the key value could be interpreted as a different type based on its
content. For example, "9110" needs quoting to ensure it is seen as a
string in yaml.
2023-06-08 17:21:46 -04:00
Kubernetes Prow Robot
336bc14e1a Merge pull request #5195 from natasha41575/updatemaintainers
add Anna to maintainers
2023-06-08 10:00:13 -07:00
natasha41575
b2c39b61bb add Anna to maintainers 2023-06-08 10:04:18 -05:00
Kubernetes Prow Robot
da31b966fb Merge pull request #5187 from koba1t/update_go_1.20
Bump to go 1.20
2023-06-07 08:28:15 -07:00
Kubernetes Prow Robot
dce94267fb Merge pull request #5030 from koba1t/fix/error_when_no_path_match
be error when no path matching
2023-06-07 07:42:13 -07:00
koba1t
d1647a51af fix e2econtainer test 2023-06-07 02:19:55 +09:00
koba1t
5b76aa9d2f update go 1.20 2023-06-06 22:39:06 +09:00
yugo kobayashi
0add0f95e2 change: components apply after all generators and transformers applied (#5170)
* change: components apply after all generator and transformer applied

* fix name for a test case

* add comment about when the components will be executed

* components are applied before transformer
2023-06-02 10:26:54 -07:00
Kubernetes Prow Robot
6ce0bf390c Merge pull request #5186 from Jefftree/gnostic-dependency
Update gnostic dependency with gnostic-models
2023-06-01 09:59:47 -07:00
Jefftree
7c98e531f2 make test-go-mod 2023-05-31 19:54:13 +00:00
Jefftree
e1ab8c79c1 Replace gnostic with gnostic-models 2023-05-31 18:14:33 +00:00
Kubernetes Prow Robot
cf3e81b590 Merge pull request #4949 from koba1t/fix/add_check_kustomization_is_empty
add check that kustomization is empty
2023-05-26 10:36:53 -07:00
koba1t
565cff2d07 update test add KustomizationFile 2023-05-25 05:13:33 +09:00
koba1t
8383b28322 fix test case handling and update a function comment 2023-05-25 04:25:10 +09:00
yugo kobayashi
e1c530e420 fix breaking examples (#5024)
* fix examples?springboot with no kustomization.yaml

* fix examples/loadHttp with legacy patch syntax
2023-05-24 10:02:50 -07:00
Natasha Sarkar
035924bc1e Merge pull request #5175 from natasha41575/release-cleanup
release cleanup
2023-05-17 10:59:48 -05:00
natasha41575
fd508f0e3a release cleanup 2023-05-17 10:41:37 -05:00
Kubernetes Prow Robot
9407e26433 Merge pull request #5155 from ephesused/eliminate-unnecessary-rnode
perf: eliminate unnecessary RNode creation
2023-05-09 15:27:55 -07:00
Natasha Sarkar
3cac8448d3 Merge pull request #5166 from natasha41575/pintoapinew
pin to api v0.13.4
2023-05-09 15:05:13 -05:00
natasha41575
84642b1fed pin to api v0.13.4 2023-05-09 14:48:02 -05:00
Natasha Sarkar
fa574866b4 Merge pull request #5165 from natasha41575/pin
pin to kyaml and cmd/config released versions
2023-05-09 14:41:36 -05:00
natasha41575
4b807107a6 pin to kyaml and cmd/config released versions 2023-05-09 14:27:34 -05:00
Kubernetes Prow Robot
6bb62dd6ef Merge pull request #5164 from kubernetes-sigs/revert-4999-fix-same-chart-multiple-versions
Revert "Fix using same helm chart with different versions"
2023-05-09 12:21:54 -07:00
Natasha Sarkar
3d6f40bd5e Revert "Fix using same helm chart with different versions (#4999)"
This reverts commit 0f244a4a07.
2023-05-09 13:16:22 -05:00
Kubernetes Prow Robot
c2bd42e774 Merge pull request #5162 from natasha41575/unpin
unpin everything
2023-05-05 13:53:16 -07:00
natasha41575
529a25d30b unpin everything 2023-05-05 15:38:19 -05:00
Natasha Sarkar
ccdc148472 Merge pull request #5161 from natasha41575/api
pin to api 0.13.3
2023-05-05 15:30:10 -05:00
natasha41575
7dcb2a50ff pin to api 0.13.3 2023-05-05 15:12:27 -05:00
Kubernetes Prow Robot
1e3215226e Merge pull request #5160 from natasha41575/cmdconfig
pin to cmd/config v0.11.2
2023-05-05 13:03:01 -07:00
natasha41575
459d0198d9 pin to cmd/config v0.11.2 2023-05-05 14:49:36 -05:00
Natasha Sarkar
3abf91644e Merge pull request #5159 from natasha41575/pintokyaml
pin to kyaml v0.14.2
2023-05-05 14:44:25 -05:00
natasha41575
1f98338481 pin to kyaml v0.14.2 2023-05-05 14:32:02 -05:00
Vijay
91078545e6 Update README.md 2023-05-05 09:57:10 +12:00
Vijay
467633c2de Update README.md 2023-05-04 12:30:46 +12:00
Vijay
e44df7b386 Delete images directory 2023-05-03 13:49:41 +12:00
Vijay
bbff6768da Update README.md 2023-05-03 13:49:15 +12:00
Vijay
0020a496f7 Merge branch 'kubernetes-sigs:master' into issue/5127 2023-05-03 13:34:39 +12:00
Kubernetes Prow Robot
5a3e920902 Merge pull request #5157 from KnVerey/update-maintainer-lists
Move inactive contributors to emeritus
2023-05-02 15:12:15 -07:00
Katrina Verey
96f893f350 Move inactive contributors to emeritus 2023-05-02 17:47:32 -04:00
Ed Overton
97c8cd7d1a perf: eliminate unnecessary RNode creation 2023-05-02 13:15:01 -04:00
Kubernetes Prow Robot
ee3f506d10 Merge pull request #5145 from SimonTheLeg/deepcopy-for-meta-types
Add DeepCopy for ResourceMeta and ObjectMeta
2023-04-25 18:14:15 -07:00
Dustin Lish
0f244a4a07 Fix using same helm chart with different versions (#4999)
* Fix using same helm chart with different versions

* Fix p.ValuesFile when version is set

* Updated: Fix using same helm chart with different versions

* Add test for issue #4813

* Use if/else for readability, add version check to absChartHome
2023-04-24 15:09:02 -07:00
Simon Bein
c79916b1ba Add DeepCopy for ResourceMeta and ObjectMeta 2023-04-24 20:19:33 +02:00
Kubernetes Prow Robot
2ce1c7cce3 Merge pull request #5133 from timja/issue-5072-non-core-api-version-namespace
Only override name of core api version
2023-04-18 14:40:58 -07:00
Tim Jacomb
75fa235498 Only override name of core api version 2023-04-18 09:41:28 +01:00
Tim Jacomb
7413c6a5fb Regression test 2023-04-18 09:41:28 +01:00
Kubernetes Prow Robot
315ed56450 Merge pull request #5130 from KnVerey/fn-framework-example
Add a rich example of fn framework for abstraction
2023-04-14 12:34:41 -07:00
Vijay
9eddc3c5a7 Update README.md
- Changes to address https://github.com/kubernetes-sigs/kustomize/issues/5127
2023-04-14 18:09:34 +12:00
Katrina Verey
38d5bf8e09 Add licence and make script use current year 2023-04-13 17:45:47 -04:00
Katrina Verey
85d623bc86 Add a rich example of fn framework for abstraction 2023-04-13 16:57:50 -04:00
koba1t
928b823d8f fix using reflect.DeepEqual for check kustomization is empty 2023-04-06 05:52:13 +09:00
koba1t
2c2b2ab825 add check that kustomization is empty 2023-04-06 05:32:08 +09:00
Kubernetes Prow Robot
d3184da4c6 Merge pull request #5111 from yutaroyamanaka/reenable-skipped-tests
Re-enable tests disabled in #3880
2023-04-05 11:45:48 -07:00
Kubernetes Prow Robot
eadb469712 Merge pull request #4924 from koba1t/chore/set_go_version_on_actions_from_gowork_file
Set go version on github actions from gowork file
2023-04-05 10:17:46 -07:00
yutaroyamanaka
2649d39fd3 docker build locally because gcr.io/kustomize-functions/e2econtainerconfig doesn't exist in the public 2023-04-04 18:22:43 +09:00
yutaroyamanaka
faab836ec9 use test helpers 2023-04-01 23:16:58 +09:00
yutaroyamanaka
c9f500cc0b add another resource for making sure an existing resource isn't affeced by a generator 2023-04-01 23:13:04 +09:00
Yutaro
42bf3c0e2b prevent all uses of YAML aliases from being overwritten by a transformer (#5096)
* return copied Node

* add a test case about imageTagTransformer for anchor scenario

* add TestPatchTransformerAnchor

* TestReplacementTransformerAnchor
2023-03-31 16:07:50 -07:00
Kubernetes Prow Robot
3b395a9da2 Merge pull request #5074 from plobsing/master
Only strip surrounding quotes if there are at least two characters.
2023-03-31 15:11:49 -07:00
Peter Lobsinger
633da991d2 Only strip surrounding quotes if there are at least two characters.
Otherwise, a value consisting of a single quote character triggers a
panic:

    go test krusty/configmaps_test.go
    --- FAIL: TestDataIsSingleQuote (0.00s)
    panic: runtime error: slice bounds out of range [1:0] [recovered]
    	panic: runtime error: slice bounds out of range [1:0]
2023-03-28 14:17:47 -07:00
Kubernetes Prow Robot
e07b8a5d15 Merge pull request #5105 from koba1t/chore/use_enable-all_option_for_golangci-lint
use enable-all on golangci-lint
2023-03-27 14:26:21 -07:00
yutaroyamanaka
71a7a7df13 re-enabled TestFnContainerGenerator with enable-gcp-services 2023-03-27 23:00:24 +09:00
yutaroyamanaka
436a047617 re-enabled TestFnContainerTransformer with e2econtainerconfig container 2023-03-27 21:33:57 +09:00
xin gu
4d70a36c25 emove the kyaml/openapi/kubernetesapi/v1_21_2/swagger.pb (#5077) 2023-03-23 10:48:31 -07:00
koba1t
304d0e951f use enable-all on golangci-lint 2023-03-23 05:54:54 +09:00
Kubernetes Prow Robot
2fdb35614d Merge pull request #5080 from chlunde/perf-2
perf: Intersection: Avoid callid AllIds inside inner loop
2023-03-20 23:03:07 -07:00
Kubernetes Prow Robot
5dff9df1f7 Merge pull request #5099 from justinsb/dont_swallow_helm_errors
Don't swallow helm execution errors
2023-03-20 12:35:09 -07:00
Kubernetes Prow Robot
84682a1159 Merge pull request #5101 from justinsb/fixlint_2
Fix unused error value
2023-03-20 12:23:07 -07:00
justinsb
c151147258 Don't swallow helm execution errors
These are otherwise hard to debug.
2023-03-20 19:14:07 +00:00
justinsb
317fcadccb Fix unused error value
The linter was complaining about err being unchecked.
2023-03-20 19:11:11 +00:00
Kubernetes Prow Robot
a2e9682002 Merge pull request #5100 from justinsb/fixlint
Fix lint task in CI
2023-03-20 10:27:19 -07:00
justinsb
5dcf0ae683 Fix lint task in CI
The lint task was failing at head, due to a nolint:exhaustive error
directive that golangci nolintlint believes is unused.

Issue seems to be https://github.com/golangci/golangci-lint/issues/3228
and seems to be a bug in golang-ci / nolintlint, using the workaround
proposed in https://github.com/golangci/golangci-lint/issues/1940
which is to clear the cache between runs.
2023-03-20 14:14:30 +00:00
Katrina Verey
ce3e394a41 Merge pull request #5091 from KnVerey/unpinEverything
Back to development mode; unpin the modules
2023-03-13 21:58:32 -04:00
Katrina Verey
0c92647760 Back to development mode; unpin the modules 2023-03-13 21:43:46 -04:00
Katrina Verey
39527da73c Merge pull request #5090 from KnVerey/pinToApi
Update api to v0.13.2
2023-03-13 21:20:22 -04:00
Katrina Verey
fa90046136 Update api to v0.13.2 2023-03-13 21:07:40 -04:00
Katrina Verey
efe1374940 Merge pull request #5089 from KnVerey/pinToCmdConfig
Update cmd/config to v0.11.1
2023-03-13 20:49:50 -04:00
Katrina Verey
b751ffe5a0 Update cmd/config to v0.11.1 2023-03-13 20:27:40 -04:00
Katrina Verey
28a2a01c29 Merge pull request #5088 from KnVerey/pinToKyaml
Update kyaml to v0.14.1
2023-03-13 19:45:23 -04:00
Katrina Verey
0c650423ed Update kyaml to v0.14.1 2023-03-13 19:24:20 -04:00
Katrina Verey
4ffc861854 Merge pull request #5087 from KnVerey/prerelease_update
Changes from local test run
2023-03-13 19:11:00 -04:00
Katrina Verey
8338873e56 Changes from local test run 2023-03-13 18:40:16 -04:00
Katrina Verey
dd520f8889 Revert strict decoding of Kustomization due to regression in anchor handling (#5073)
* Revert strict decoding of Kustomization due to regression in anchor handling

* Empty commit
2023-03-13 13:46:47 -07:00
Carl Henrik Lunde
4842d8be60 perf: Intersection: Avoid callid AllIds inside inner loop
This shaves of another 8.5 seconds (one third) of the remaining execution
time for a kustomization tree with 4000 documents, reducing the execution
time from 27.46s to 18.94s

     0.02s 0.062% 11.14%      8.45s 26.36%  sigs.k8s.io/kustomize/api/internal/accumulator.(*ResAccumulator).Intersection
     0.06s  0.19% 11.32%      8.32s 25.95%  sigs.k8s.io/kustomize/api/resmap.(*resWrangler).AllIds

before

    (pprof) top25 -cum
    Showing nodes accounting for 3.63s, 11.32% of 32.06s total
    Dropped 614 nodes (cum <= 0.16s)
    Showing top 25 nodes out of 171
        flat  flat%   sum%        cum   cum%
            0     0%     0%     27.46s 85.65%  github.com/spf13/cobra.(*Command).Execute
            0     0%     0%     27.46s 85.65%  github.com/spf13/cobra.(*Command).ExecuteC
            0     0%     0%     27.46s 85.65%  github.com/spf13/cobra.(*Command).execute
            0     0%     0%     27.46s 85.65%  main.main
            0     0%     0%     27.46s 85.65%  runtime.main
            0     0%     0%     27.46s 85.65%  sigs.k8s.io/kustomize/kustomize/v5/commands/build.NewCmdBuild.func1
            0     0%     0%     26.95s 84.06%  sigs.k8s.io/kustomize/api/krusty.(*Kustomizer).Run
            0     0%     0%     22.09s 68.90%  sigs.k8s.io/kustomize/api/internal/target.(*KustTarget).MakeCustomizedResMap (inline)
            0     0%     0%     22.09s 68.90%  sigs.k8s.io/kustomize/api/internal/target.(*KustTarget).makeCustomizedResMap
        0.29s   0.9%   0.9%     20.96s 65.38%  sigs.k8s.io/kustomize/api/resource.(*Resource).CurId
            0     0%   0.9%     13.61s 42.45%  sigs.k8s.io/kustomize/api/resmap.(*resWrangler).Append
            0     0%   0.9%     13.60s 42.42%  sigs.k8s.io/kustomize/api/resmap.(*resWrangler).GetMatchingResourcesByCurrentId (partial-inline)
        0.14s  0.44%  1.34%     13.60s 42.42%  sigs.k8s.io/kustomize/api/resmap.(*resWrangler).filteredById
        0.05s  0.16%  1.50%     12.91s 40.27%  sigs.k8s.io/kustomize/api/resmap.GetCurrentId
        0.25s  0.78%  2.28%     12.48s 38.93%  sigs.k8s.io/kustomize/api/resource.(*Resource).GetGvk (inline)
        0.49s  1.53%  3.81%     12.23s 38.15%  sigs.k8s.io/kustomize/kyaml/resid.GvkFromNode
            0     0%  3.81%     11.61s 36.21%  sigs.k8s.io/kustomize/api/internal/target.(*KustTarget).IgnoreLocal
            0     0%  3.81%     10.47s 32.66%  sigs.k8s.io/kustomize/api/internal/target.(*KustTarget).AccumulateTarget
            0     0%  3.81%     10.47s 32.66%  sigs.k8s.io/kustomize/api/internal/target.(*KustTarget).accumulateTarget
        0.01s 0.031%  3.84%     10.46s 32.63%  sigs.k8s.io/kustomize/api/internal/target.(*KustTarget).accumulateResources
            0     0%  3.84%     10.43s 32.53%  sigs.k8s.io/kustomize/api/internal/target.(*KustTarget).accumulateDirectory
        0.64s  2.00%  5.83%     10.12s 31.57%  sigs.k8s.io/kustomize/kyaml/yaml.visitMappingNodeFields
        1.68s  5.24% 11.07%      9.48s 29.57%  sigs.k8s.io/kustomize/kyaml/yaml.visitFieldsWhileTrue
        0.02s 0.062% 11.14%      8.45s 26.36%  sigs.k8s.io/kustomize/api/internal/accumulator.(*ResAccumulator).Intersection
        0.06s  0.19% 11.32%      8.32s 25.95%  sigs.k8s.io/kustomize/api/resmap.(*resWrangler).AllIds

after

    (pprof) top30 -cum
    Showing nodes accounting for 5.04s, 22.63% of 22.27s total
    Dropped 540 nodes (cum <= 0.11s)
    Showing top 30 nodes out of 209
        flat  flat%   sum%        cum   cum%
            0     0%     0%     18.94s 85.05%  github.com/spf13/cobra.(*Command).Execute
            0     0%     0%     18.94s 85.05%  github.com/spf13/cobra.(*Command).ExecuteC
            0     0%     0%     18.94s 85.05%  github.com/spf13/cobra.(*Command).execute
            0     0%     0%     18.94s 85.05%  main.main
            0     0%     0%     18.94s 85.05%  runtime.main
            0     0%     0%     18.94s 85.05%  sigs.k8s.io/kustomize/kustomize/v5/commands/build.NewCmdBuild.func1
            0     0%     0%     18.40s 82.62%  sigs.k8s.io/kustomize/api/krusty.(*Kustomizer).Run
            0     0%     0%     13.65s 61.29%  sigs.k8s.io/kustomize/api/internal/target.(*KustTarget).MakeCustomizedResMap (inline)
            0     0%     0%     13.65s 61.29%  sigs.k8s.io/kustomize/api/internal/target.(*KustTarget).makeCustomizedResMap
            0     0%     0%     13.52s 60.71%  sigs.k8s.io/kustomize/api/resmap.(*resWrangler).Append
            0     0%     0%     13.44s 60.35%  sigs.k8s.io/kustomize/api/resmap.(*resWrangler).GetMatchingResourcesByCurrentId (inline)
        0.16s  0.72%  0.72%     13.44s 60.35%  sigs.k8s.io/kustomize/api/resmap.(*resWrangler).filteredById
        0.04s  0.18%   0.9%     12.54s 56.31%  sigs.k8s.io/kustomize/api/resmap.GetCurrentId
        0.19s  0.85%  1.75%     12.49s 56.08%  sigs.k8s.io/kustomize/api/resource.(*Resource).CurId
            0     0%  1.75%     10.37s 46.56%  sigs.k8s.io/kustomize/api/internal/target.(*KustTarget).AccumulateTarget
            0     0%  1.75%     10.37s 46.56%  sigs.k8s.io/kustomize/api/internal/target.(*KustTarget).accumulateResources
            0     0%  1.75%     10.37s 46.56%  sigs.k8s.io/kustomize/api/internal/target.(*KustTarget).accumulateTarget
            0     0%  1.75%     10.34s 46.43%  sigs.k8s.io/kustomize/api/internal/target.(*KustTarget).accumulateDirectory
        0.19s  0.85%  2.60%      7.82s 35.11%  sigs.k8s.io/kustomize/api/resource.(*Resource).GetGvk (inline)
        0.42s  1.89%  4.49%      7.63s 34.26%  sigs.k8s.io/kustomize/kyaml/resid.GvkFromNode
        0.26s  1.17%  5.66%      6.01s 26.99%  sigs.k8s.io/kustomize/kyaml/yaml.visitMappingNodeFields
            0     0%  5.66%      5.76s 25.86%  sigs.k8s.io/kustomize/api/internal/accumulator.(*ResAccumulator).MergeAccumulator
        1.12s  5.03% 10.69%      5.75s 25.82%  sigs.k8s.io/kustomize/kyaml/yaml.visitFieldsWhileTrue
            0     0% 10.69%      5.57s 25.01%  sigs.k8s.io/kustomize/api/resmap.(*resWrangler).appendAll (inline)
            0     0% 10.69%      5.55s 24.92%  sigs.k8s.io/kustomize/api/internal/accumulator.(*ResAccumulator).AppendAll (inline)
            0     0% 10.69%      5.55s 24.92%  sigs.k8s.io/kustomize/api/resmap.(*resWrangler).AppendAll
            0     0% 10.69%      4.73s 21.24%  sigs.k8s.io/kustomize/api/internal/builtins.(*SortOrderTransformerPlugin).Transform
            0     0% 10.69%      4.73s 21.24%  sigs.k8s.io/kustomize/api/krusty.(*Kustomizer).applySortOrder
            0     0% 10.69%      4.72s 21.19%  sigs.k8s.io/kustomize/api/internal/builtins.applyOrdering
        2.66s 11.94% 22.63%      4.63s 20.79%  sigs.k8s.io/kustomize/kyaml/yaml.visitMappingNodeFields.func2
2023-03-12 15:50:11 +01:00
Kubernetes Prow Robot
bf6e6ad33b Merge pull request #5085 from koba1t/chore/update_golangci_to_1.51.2
update golangci-lint to v1.51.2
2023-03-10 14:28:39 -08:00
koba1t
e1094da3cf skip unrelevant lint 2023-03-11 05:11:47 +09:00
koba1t
7d150ce973 Revert "use enable-all on golangci-lint"
This reverts commit 39264a7057.
2023-03-11 05:08:25 +09:00
koba1t
39264a7057 use enable-all on golangci-lint 2023-03-09 05:25:19 +09:00
koba1t
736e166168 update golangci-lint to 1.51.2 2023-03-09 05:08:25 +09:00
Kubernetes Prow Robot
e8b521e3ab Merge pull request #5053 from kubernetes-sigs/dependabot/go_modules/functions/examples/application-cr/image/golang.org/x/net-0.7.0
Bump golang.org/x/net from 0.4.0 to 0.7.0 in /functions/examples/application-cr/image
2023-02-28 11:33:16 -08:00
koba1t
694b3c9318 Add the test cases for check the file when edit add command 2023-03-01 04:20:59 +09:00
dependabot[bot]
a4954d386a Bump golang.org/x/net in /functions/examples/application-cr/image
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.4.0 to 0.7.0.
- [Release notes](https://github.com/golang/net/releases)
- [Commits](https://github.com/golang/net/compare/v0.4.0...v0.7.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-27 18:17:11 +00:00
Kubernetes Prow Robot
976193ce70 Merge pull request #5054 from kubernetes-sigs/dependabot/go_modules/cmd/depprobcheck/golang.org/x/net-0.7.0
Bump golang.org/x/net from 0.4.0 to 0.7.0 in /cmd/depprobcheck
2023-02-27 10:08:39 -08:00
dependabot[bot]
ee0b26601b Bump golang.org/x/net from 0.4.0 to 0.7.0 in /cmd/depprobcheck
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.4.0 to 0.7.0.
- [Release notes](https://github.com/golang/net/releases)
- [Commits](https://github.com/golang/net/compare/v0.4.0...v0.7.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-27 16:35:34 +00:00
Kubernetes Prow Robot
78e310231e Merge pull request #5065 from kubernetes-sigs/dependabot/go_modules/cmd/depprobcheck/golang.org/x/crypto-0.1.0
Bump golang.org/x/crypto from 0.0.0-20210921155107-089bfa567519 to 0.1.0 in /cmd/depprobcheck
2023-02-27 08:34:38 -08:00
Kubernetes Prow Robot
ffa554b371 Merge pull request #5064 from kubernetes-sigs/dependabot/go_modules/functions/examples/application-cr/image/golang.org/x/crypto-0.1.0
Bump golang.org/x/crypto from 0.0.0-20210921155107-089bfa567519 to 0.1.0 in /functions/examples/application-cr/image
2023-02-27 08:26:39 -08:00
dependabot[bot]
68a0fc95da Bump golang.org/x/crypto in /cmd/depprobcheck
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.0.0-20210921155107-089bfa567519 to 0.1.0.
- [Release notes](https://github.com/golang/crypto/releases)
- [Commits](https://github.com/golang/crypto/commits/v0.1.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-25 03:30:10 +00:00
dependabot[bot]
9b43e76947 Bump golang.org/x/crypto in /functions/examples/application-cr/image
Bumps [golang.org/x/crypto](https://github.com/golang/crypto) from 0.0.0-20210921155107-089bfa567519 to 0.1.0.
- [Release notes](https://github.com/golang/crypto/releases)
- [Commits](https://github.com/golang/crypto/commits/v0.1.0)

---
updated-dependencies:
- dependency-name: golang.org/x/crypto
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-02-25 00:50:47 +00:00
Kubernetes Prow Robot
adf760e246 Merge pull request #5058 from ephesused/optimize-gvk-version
perf: optimize Gvk.ApiVersion()
2023-02-21 11:57:56 -08:00
Kubernetes Prow Robot
7a89df8350 Merge pull request #5048 from cailynse/issue-5039
Remove Log Assignment to Stdout
2023-02-21 11:23:56 -08:00
Ed Overton
93d7511b38 perf: optimize Gvk.ApiVersion()
Convert Gvk.ApiVersion() from using strings.Builder to raw string
concatenation. The logic in Gvk.ApiVersion() is simple enough that
raw concatenation executes quicker and consumes less memory.
2023-02-21 11:02:57 -05:00
Cailyn Edwards
7c33fe30b7 Remove Log Assignment to Stdout 2023-02-21 10:53:22 -05:00
koba1t
cd49194383 fix tests 2023-02-09 05:35:45 +09:00
Kubernetes Prow Robot
22dbd3eb17 Merge pull request #5038 from KnVerey/unpin-modules
Update all modules to latest releases, but unpinned
2023-02-08 11:08:44 -08:00
koba1t
53a4134379 fix error handling and test 2023-02-09 04:01:30 +09:00
Katrina Verey
51e2714408 Back to development mode; unpin the modules 2023-02-07 19:56:39 -05:00
Katrina Verey
d825beff27 Update all modules to latest releases 2023-02-07 19:56:11 -05:00
Katrina Verey
aa4eb59bb0 Fix constant reference in instructions 2023-02-07 19:54:58 -05:00
Katrina Verey
00d450cce7 Revert plugin exclusion to name sanity check 2023-02-07 19:47:21 -05:00
Kubernetes Prow Robot
a090ceac6c Merge pull request #5026 from KnVerey/update_releasing_instr
Update releasing workflow
2023-02-07 13:14:58 -08:00
Katrina Verey
63c37b1780 Update releasing/README.md
Co-authored-by: Cailyn <cailyn.s.e@gmail.com>
2023-02-06 16:49:19 -05:00
koba1t
dfd2d7600d be error when no path match 2023-02-04 00:57:56 +09:00
Kubernetes Prow Robot
0fd385d719 Merge pull request #4946 from researchapps/add/github-token-install
add GitHub token to install_kustomize.sh
2023-02-02 13:58:42 -08:00
Katrina Verey
57d8583887 Fix lint errors 2023-02-02 14:25:20 -05:00
Katrina Verey
9c116e9031 Bespoke mod edits no longer needed if gorepomod pins all modules 2023-02-02 14:23:23 -05:00
Katrina Verey
e6c16a6ddc Restore previous test-go-mod and commit changes 2023-02-02 14:20:13 -05:00
Katrina Verey
03669a1804 Improve error message and fix typo in iampolicygenerator module name 2023-02-02 14:15:40 -05:00
vsoch
3c44db8746 add GitHub token to install_kustomize.sh
Signed-off-by: vsoch <vsoch@users.noreply.github.com>
2023-02-02 12:08:20 -07:00
Katrina Verey
9a1a203b52 Update example targets 2023-02-02 12:28:37 -05:00
Katrina Verey
8b51c295a1 Allow gorepomod to update plugin mod files 2023-02-02 11:33:46 -05:00
Kubernetes Prow Robot
738ca56ccd Merge pull request #5027 from KnVerey/remove-replaces
Remove leftover replace statements
2023-02-02 08:32:41 -08:00
Katrina Verey
f901b4a5fd Remove leftover replace statements 2023-02-02 11:23:00 -05:00
Katrina Verey
4fff8399ea Update releasing instructions 2023-02-02 11:22:00 -05:00
Katrina Verey
e532d6f1a1 Merge pull request #5025 from KnVerey/pinToApi
Update api to v0.13.1
2023-02-02 10:58:41 -05:00
Katrina Verey
db2a3800ed Update api to v0.13.1 2023-02-02 10:45:39 -05:00
Kubernetes Prow Robot
183928e6ba Merge pull request #5023 from KnVerey/issue4998
Fix regression with scp-style urls with only one path element
2023-02-01 23:41:29 -08:00
Katrina Verey
c0e2030905 Fix regression with scp-style urls with only one path element 2023-02-01 22:19:40 -05:00
Kubernetes Prow Robot
87c428e7cd Merge pull request #5021 from KnVerey/module_version_v5
Bump kustomize module to v5
2023-02-01 17:03:29 -08:00
Katrina Verey
f5ad795995 Bump kustomize module to v5 2023-02-01 19:01:08 -05:00
Kubernetes Prow Robot
f851cc7181 Merge pull request #5020 from KnVerey/pinToCmdConfig
Pin to cmd config
2023-02-01 14:39:36 -08:00
Katrina Verey
7e3ad53890 Allow cloud build to authenticate to gh when generating changelog 2023-02-01 17:25:57 -05:00
Katrina Verey
5cdc080406 Update cmd/config to v0.11.0 2023-02-01 17:22:46 -05:00
Katrina Verey
10fb04cdf2 Merge pull request #5019 from KnVerey/pinToKyaml
Update kyaml to v0.14.0
2023-02-01 17:09:20 -05:00
Katrina Verey
ea8fc77f2f Update kyaml in the secondary modules 2023-02-01 16:55:56 -05:00
Katrina Verey
e9507c940d Update kyaml to v0.14.0 2023-02-01 16:44:34 -05:00
Katrina Verey
bea105d793 Merge pull request #5017 from KnVerey/fix-changelog-unauthed
Don't have empty string when no auth info
2023-02-01 16:30:39 -05:00
Katrina Verey
e4d7eaa479 Don't have empty string when no auth info 2023-02-01 16:28:20 -05:00
Kubernetes Prow Robot
85949329b8 Merge pull request #5015 from KnVerey/changelog-auth
Allow authenticated Github use in changelog script and improve error messages
2023-02-01 12:59:36 -08:00
Katrina Verey
0c34cf4192 Allow authenticated Github use in changelog script and improve error messages 2023-02-01 15:39:38 -05:00
Cailyn
95edcc0681 Update Versioning to Improve Output (#5000)
* Update Versioning to Improve Output

* Always get commit from build info, always get date and version from ldflag

* Just replace broken main output with semver and deprecate short flag as is

---------

Co-authored-by: Katrina Verey <katrina.verey@shopify.com>
2023-02-01 11:25:37 -08:00
Anna Song
9d8ed39d3d Localize helm additionValuesFiles (#5013) 2023-02-01 10:39:20 -08:00
Natasha Sarkar
1957d5c746 support for more helm template args (#4926)
* support for more helm template args

* move templateArgs and unit tests to api/types

* undo package name change

* use our own simple helm chart instead of forking one

* add argument to AsHelmArgs

* code review

* lint errors
2023-02-01 10:19:05 -08:00
Anna Song
236166097e Add localize command handle (#4959)
* Add localize command handle

* Align to kustomize command conventions

* Print success msg
2023-02-01 08:11:07 -08:00
Kubernetes Prow Robot
3370177b9d Merge pull request #5012 from natasha41575/reponotfileerr
make TestResourcesRepoNotFile even less specific
2023-01-31 11:16:50 -08:00
natasha41575
c8b112c79f make TestResourcesRepoNotFile even less specific 2023-01-31 12:58:55 -06:00
Katrina Verey
d91e31cf18 Run test-go-mod unpinned (#5011)
* Remove go module ci job

* Add script that runs go mod tidy with replace statements

* Invoke one script from the makefile and pass in the command to run in the pinned context

---------

Co-authored-by: Anna Song <annasong@google.com>
2023-01-31 09:56:48 -08:00
Kubernetes Prow Robot
00b0bd8473 Merge pull request #5010 from annasong20/expose-localize-dst
Expose path to `localize` destination
2023-01-30 18:36:48 -08:00
Anna Song
e2aff13587 Expose path to localize destination 2023-01-30 15:42:58 -08:00
Anna Song
361154dabc Localize HelmChartInflationGenerator (#5007)
* Localize HelmChartInflationGenerator

* Add explicit inline generators test
2023-01-30 13:16:48 -08:00
Kubernetes Prow Robot
7db330d2cc Merge pull request #5009 from kubernetes-sigs/no-partial-releases
Warn against partial releases
2023-01-30 13:04:49 -08:00
Katrina Verey
e9f47abcc1 Warn against partial releases 2023-01-30 15:48:58 -05:00
Kubernetes Prow Robot
58defe31e7 Merge pull request #4967 from pmalek/add-lock-for-kubernetesOpenAPIVersion
fix: add lock for kubernetesOpenAPIVersion
2023-01-27 17:54:32 -08:00
Kubernetes Prow Robot
ee4fb17170 Merge pull request #4989 from annasong20/localize-generators-configmap-secret
Localize ConfigMapGenerator, SecretGenerator
2023-01-27 14:22:39 -08:00
Anna Song
142360b0ed Localize ConfigMapGenerator, SecretGenerator 2023-01-27 14:06:40 -08:00
Patryk Małek
f7c3fce6a5 fix(kyaml): add lock for schema related globals 2023-01-27 09:40:47 +01:00
Kubernetes Prow Robot
af3e8ee353 Merge pull request #5004 from cailynse/fix-runner-test
Make TestResourcesRepoNotFile Less Specific
2023-01-26 13:56:25 -08:00
Cailyn Edwards
90281a62e0 Make TestResourcesRepoNotFile Less Specific 2023-01-26 16:39:30 -05:00
Anna Song
fb294921f5 Localize helm fields (#4978)
* Localize helm fields

* Address readability feedback

* Handle edge cases

* Improve readability

Split copyChartHome and use existence to prevent repeated copying.
2023-01-26 12:56:26 -08:00
Kubernetes Prow Robot
af9a13111b Merge pull request #4944 from ephesused/optimize-getannotations-2
Refactor mapping node traversal and optimize RNode.GetAnnotations and RNode.GetLabels
2023-01-26 12:18:25 -08:00
Kubernetes Prow Robot
279ad3e815 Merge pull request #4995 from KnVerey/follow-up-fixes
Follow up fixes
2023-01-24 15:48:10 -08:00
Kubernetes Prow Robot
96351a9278 Merge pull request #4990 from brianpursley/improve-panic-error
Improve panic error message to include the parse error.
2023-01-24 15:33:56 -08:00
Katrina Verey
8b21844b10 Do not use filepath.Separator for splitting URLs 2023-01-24 18:10:34 -05:00
Katrina Verey
d315600e5e remove redundant type meta in tests 2023-01-24 17:59:36 -05:00
Kubernetes Prow Robot
8f75682b9c Merge pull request #4834 from elisshafer/generators/retain_disable_suffix_hash
api/resource: retain disableNameSuffixHash on merge and replace
2023-01-24 09:50:19 -08:00
Kubernetes Prow Robot
659c0ee156 Merge pull request #4994 from annasong20/remove-git-suffix
Fix `RepoSpec` CI failures on master
2023-01-23 13:32:17 -08:00
Anna Song
298b87a223 Fix master
Fix RepoSpec build errors as result of merging 2 RepoSpec PRs in parallel
2023-01-23 13:21:55 -08:00
Kubernetes Prow Robot
a69092c4b7 Merge pull request #4986 from KnVerey/repospec_custom_usernames
repospec: support ssh urls with ssh certificates
2023-01-20 13:23:54 -08:00
Kubernetes Prow Robot
0a1aa7c2cb Merge pull request #4985 from KnVerey/repospec-git-suffix
Proposal: Remove RepoSpec manipulation of .git suffix
2023-01-20 13:16:01 -08:00
Kubernetes Prow Robot
89d3ca1757 Merge pull request #4973 from KnVerey/remove-inventory-field
Remove long-ignored Inventory field from Kustomization type
2023-01-20 13:15:53 -08:00
Katrina Verey
d858ed82fa Merge pull request #4992 from RahulGautamSingh/patch-1
fix(docs): update link to plugin doc
2023-01-20 13:11:12 -05:00
RahulGautamSingh
f47f897440 fix(docs): update link to plugin doc 2023-01-20 13:36:20 +05:30
Brian Pursley
ace8132edc Improve panic error message to include the parse error. 2023-01-18 21:37:13 -05:00
Katrina Verey
2405da65d2 repospec: support ssh urls with ssh certificates 2023-01-17 23:25:07 -05:00
Katrina Verey
7e000aa820 Remove manipulation of .git suffix, which is just a conventional part of the directory name 2023-01-17 23:04:16 -05:00
Kubernetes Prow Robot
dbc11a43a8 Merge pull request #4983 from KnVerey/repospec_separators
Refactor parseGitURL
2023-01-17 17:22:34 -08:00
Kubernetes Prow Robot
def01f0af8 Merge pull request #4947 from Azhovan/jabar/allow-path-starting-forward-slash
feat: Allow path starting with slash
2023-01-17 13:04:33 -08:00
Kubernetes Prow Robot
ec4d1e802b Merge pull request #4974 from annasong20/expose-localize-test-helpers
Expose localize test helpers
2023-01-17 12:28:41 -08:00
Anna Song
7899b80a00 Localize patch, ReplacementTransformer (#4943)
* Localize PatchStrategicMergeTransformer, ReplacementTransformer

* Improve readability
2023-01-17 12:28:34 -08:00
Katrina Verey
00208394d6 Refactor parseGitURL to consolidate code paths, improve error handling 2023-01-16 20:36:19 -05:00
Kubernetes Prow Robot
db7b057956 Merge pull request #4965 from olivierlemasle/puerkitobio-urlesc
Bump k8s.io/kube-openapi to remove archived dependency
2023-01-13 16:10:13 -08:00
Olivier Lemasle
aaf9d39975 Bump k8s.io/kube-openapi to remove archived dependency
Bump k8s.io/kube-openapi to remove archived dependency github.com/PuerkitoBio/urlesc
2023-01-13 20:50:59 +01:00
Cailyn
8ab4b8d167 remove direct dependency on github/pkg/errors (#4970) 2023-01-13 10:52:25 -08:00
Kubernetes Prow Robot
2b7eb6d92a Merge pull request #4980 from KnVerey/outdated_sums
Uncommitted updates from running go mod tidy and go work sync
2023-01-13 10:02:26 -08:00
Katrina Verey
2b38c12c83 Add uncommitted plugin change and missing makefile dep 2023-01-13 12:53:35 -05:00
Katrina Verey
18a60ef036 Uncommitted updated from running go mod tidy and go work sync 2023-01-13 12:53:11 -05:00
Katrina Verey
d70315fed6 Remove Inventory field from Kustomization
This field has not done anything since v3.5.5. It was missed in the cleanup in https://github.com/kubernetes-sigs/kustomize/pull/2421
2023-01-12 19:11:44 -05:00
Anna Song
dc34520ac1 Expose localizer test helpers
Expose helpers for later use by localize command handle tests
2023-01-12 10:14:44 -08:00
Kubernetes Prow Robot
da5d572df2 Merge pull request #4954 from KnVerey/more_repospec
Iteration on parseHostSpec refactor
2023-01-10 13:25:26 -08:00
Katrina Verey
3134e9b0c2 Better SCP colon-must-be-after-slash test 2023-01-10 16:14:54 -05:00
Katrina Verey
c2885642d6 Remove unused param 2023-01-10 15:01:29 -05:00
Katrina Verey
a885ee12c6 Add test for behaviour of scp-like non-github that incorrectly uses slash 2023-01-09 17:32:29 -05:00
Katrina Verey
1a201ab913 do not validate against http+usernames after all 2023-01-09 17:25:10 -05:00
Katrina Verey
240282fc6f Allow file paths that look like usernames 2023-01-09 17:15:40 -05:00
Kubernetes Prow Robot
445622147f Merge pull request #4889 from fengshunli/vuln
fix: all module net and text dependent package CVE-2022-41717 and CVE-2022-32149 vulnerabilities
2023-01-09 11:45:29 -08:00
Katrina Verey
ddf14ea688 Deprecate git:: stripping 2023-01-09 13:18:11 -05:00
Katrina Verey
64d2366e87 Naming changes from rebase 2023-01-09 13:15:26 -05:00
Katrina Verey
06999462e7 Make Github less special 2023-01-09 13:13:28 -05:00
Katrina Verey
2591303430 Add test case from github docs 2023-01-09 13:13:28 -05:00
Katrina Verey
150134758f Show change vs master on accepted but invalid ssh-like urls 2023-01-09 13:13:28 -05:00
Katrina Verey
43d96ba91b Address feedback on correctness of SCP/username validations 2023-01-09 13:13:28 -05:00
Katrina Verey
4821259f01 Stop handling mysterious gh: prefix in remote URLs 2023-01-09 13:13:27 -05:00
Katrina Verey
7e6cc7aafb Review feedback 2023-01-09 13:13:27 -05:00
Katrina Verey
dc05fa153f Additional repospec refactoring 2023-01-09 13:13:27 -05:00
Anna Song
fbb94584dc Refactor parseHostSpec
Fix ssh parsing in issue 4847
2023-01-09 13:13:25 -05:00
Kishore Jagannath
772fafa892 Rename Orgrepo and Path (#4922)
* initial changes to rename OrgRepo to RepoPath

* changes to rename Path to KustRootPath

* addressed review comments

* addressed review comments

* docs: Add documentation for namespace transformer

Add a short description of the namespace transformer and example
usage to examples/transformerconfigs/README.md.

References: #629
Signed-off-by: Lars Kellogg-Stedman <lars@oddbit.com>

* Localize patchesJson6902, patchesStrategicMerge, replacements (#4904)

* Localize patchesJson6902, patchesStrategicMerge, replacements

* Address code review feedback

* Improve readability
* Remove deprecation warning check

* Load legacy kustomization fields for `localize` (#4918)

* Load legacy kustomization

* Expose loadKustFile in kusttarget

* remove FixKustomizationPreUnmarshalling

* remove deprecated cfg and fn commands (#4930)

* remove deprecated cfg and fn commands

* fix lint error

* run gofmt

* Localize PatchTransformer, PatchJson6902Transformer (#4920)

* Localize patches, patchesJson6902 custom transformers

* Improve readability

* Localize fields: openapi, configurations, crds (#4907)

* Localize openapi, configurations, crds

* Add integration test

* Move krusty test

* Address code review feedback

* Implement locRootPath (#4909)

* Implement locRootPath, and include userinfo, port in locFilePath

* Strip userinfo, port

* Improve readability

* Localize legacy fields

* Localize resources (#4912)

* Localize resources

* Improve readability

* Add integration tests

* Group test helper functions

* Remove Functionality that Pulls Env Variables from Empty Keys

* Update api/kv/kv.go

Co-authored-by: Katrina Verey <kn.verey@gmail.com>

* refactor Unmarshal Kustomization struct code

* improve error messages

* Run go mod tidy on all modules before update

* Update sigs.k8s.io/yaml to 1.3.0

* fixed test failure because of latest commits

Signed-off-by: Lars Kellogg-Stedman <lars@oddbit.com>
Co-authored-by: Lars Kellogg-Stedman <lars@oddbit.com>
Co-authored-by: Anna Song <annasong@google.com>
Co-authored-by: yugo kobayashi <kobdotsh@gmail.com>
Co-authored-by: Natasha Sarkar <natashasarkar@google.com>
Co-authored-by: Cailyn Edwards <cailyn.edwards@shopify.com>
Co-authored-by: Cailyn <cailyn.s.e@gmail.com>
Co-authored-by: Katrina Verey <kn.verey@gmail.com>
Co-authored-by: Katrina Verey <katrina.verey@shopify.com>
2023-01-09 08:45:29 -08:00
fsl
32f31c34ba fix: all module net and text dependent package CVE-2022-41717 and CVE-2022-32149 vulnerabilities
Signed-off-by: fsl <1171313930@qq.com>
2023-01-09 11:27:35 +08:00
Kubernetes Prow Robot
9bc75c16d9 Merge pull request #4960 from KnVerey/update-sigs-yaml
Update sigs.k8s.io/yaml to v1.3.0
2023-01-06 13:37:27 -08:00
Katrina Verey
5be179305a Update sigs.k8s.io/yaml to 1.3.0 2023-01-06 16:23:17 -05:00
Katrina Verey
cb6553430d Run go mod tidy on all modules before update 2023-01-06 16:21:44 -05:00
Kubernetes Prow Robot
c6ca3ff799 Merge pull request #4929 from koba1t/refactor/cleanup_Unmarshal_kustomization
Error on duplicate fields in Kustomization
2023-01-06 10:37:59 -08:00
koba1t
6489e35b7c improve error messages 2023-01-07 03:30:16 +09:00
Kubernetes Prow Robot
1308d905fa Merge pull request #4957 from cailynse/update-configMapGenerator-4731
Remove Functionality that Pulls Env Variables from Empty Keys
2023-01-05 13:19:58 -08:00
Cailyn
6c79645fb0 Update api/kv/kv.go
Co-authored-by: Katrina Verey <kn.verey@gmail.com>
2023-01-05 14:39:02 -05:00
Cailyn Edwards
b7746d09e4 Remove Functionality that Pulls Env Variables from Empty Keys 2023-01-05 12:54:48 -05:00
Anna Song
06da3b96a2 Localize resources (#4912)
* Localize resources

* Improve readability

* Add integration tests

* Group test helper functions
2023-01-05 08:47:59 -08:00
Kubernetes Prow Robot
6949c83840 Merge pull request #4933 from annasong20/localize-legacy
Localize legacy fields
2023-01-04 09:06:03 -08:00
Jabar Asadi
368697f8ef feat: Allow paths starting with slash 2022-12-26 17:18:08 +01:00
Anna Song
3022dd2931 Localize legacy fields 2022-12-22 17:21:16 -05:00
Anna Song
aec35009ed Implement locRootPath (#4909)
* Implement locRootPath, and include userinfo, port in locFilePath

* Strip userinfo, port

* Improve readability
2022-12-22 12:15:26 -08:00
Anna Song
de6162625f Localize fields: openapi, configurations, crds (#4907)
* Localize openapi, configurations, crds

* Add integration test

* Move krusty test

* Address code review feedback
2022-12-22 12:07:26 -08:00
Ed Overton
a0e94c1642 fix: correct visitMappingNodeFields
This commit adjusts visitMappingNodeFields so that it no longer assumes
the mapping node has unique keys.
2022-12-22 11:51:15 -05:00
Ed Overton
20b0d3c7ce perf: optimize RNode GetAnnotations and GetLabels
This commit optimizes in three ways:

1. For heavily used functions, allocate memory to avoid overhead
   associated with map and array re-sizing.
2. Where appropriate, limit annotation and label retrievals to only the
   desired keys.
3. Adjust annotation and label retrieval to avoid unnecessary temporary
   object creation.
2022-12-20 17:24:35 -05:00
Ed Overton
194a017c81 refactor: single function to visit mapping node content
Refactor mapping node content traversal so that all code paths execute
through the same root function.
2022-12-20 17:21:05 -05:00
Anna Song
a1bfab382a Localize PatchTransformer, PatchJson6902Transformer (#4920)
* Localize patches, patchesJson6902 custom transformers

* Improve readability
2022-12-16 09:52:17 -08:00
Natasha Sarkar
ef60d5f9bb remove deprecated cfg and fn commands (#4930)
* remove deprecated cfg and fn commands

* fix lint error

* run gofmt
2022-12-14 12:15:35 -08:00
yugo kobayashi
5fed0f76c8 refactor Unmarshal Kustomization struct code 2022-12-13 21:04:50 +00:00
Kubernetes Prow Robot
e3981daf0e Merge pull request #4923 from koba1t/chore/remove_FixKustomizationPreUnmarshalling
Remove fix kustomization step before Unmarshalling the yaml structure
2022-12-13 12:11:35 -08:00
yugo kobayashi
faddb49c89 remove FixKustomizationPreUnmarshalling 2022-12-13 18:50:25 +00:00
Anna Song
4cccb838ce Load legacy kustomization fields for localize (#4918)
* Load legacy kustomization

* Expose loadKustFile in kusttarget
2022-12-13 08:19:34 -08:00
Anna Song
292d18983d Localize patchesJson6902, patchesStrategicMerge, replacements (#4904)
* Localize patchesJson6902, patchesStrategicMerge, replacements

* Address code review feedback

* Improve readability
* Remove deprecation warning check
2022-12-12 10:41:33 -08:00
Eli Shafer
2d854c46dd resource/api: update test to use a more specific kustomization 2022-12-11 22:58:41 -08:00
Kubernetes Prow Robot
55edae1648 Merge pull request #4906 from larsks/docs/namespace-transformer
docs: Add documentation for namespace transformer
2022-12-09 13:27:35 -08:00
Lars Kellogg-Stedman
d5e1940fc2 docs: Add documentation for namespace transformer
Add a short description of the namespace transformer and example
usage to examples/transformerconfigs/README.md.

References: #629
Signed-off-by: Lars Kellogg-Stedman <lars@oddbit.com>
2022-12-09 14:05:16 -05:00
yugo kobayashi
ffd45f6893 Set go version on github actions from gowork file 2022-12-09 18:14:09 +00:00
Kubernetes Prow Robot
6cf7014b2c Merge pull request #4919 from ChristopherFry/cfry/name-suffix-transformer
Allow overriding of name suffix transformer default configuration
2022-12-08 13:20:23 -08:00
Christopher Fry
8a6602db94 Allow name suffix transformer configuration to be overridden 2022-12-08 20:10:05 +00:00
Eli Shafer
24bf1d07e7 api/resource: add new test for inline options. 2022-12-07 22:18:37 -08:00
Eli Shafer
487703ee8f api/resource: retain disableNameSuffixHash on merge. 2022-12-07 22:18:37 -08:00
Natasha Sarkar
2db573b6a0 drop support for legacy patches (#4911)
* drop support for legacy patches

* fix CI
2022-12-07 18:06:24 -08:00
Kubernetes Prow Robot
8a869f6045 Merge pull request #4882 from ChristopherFry/cfry/user-config-priority
Add test ensuring user configuration overrides default configuration
2022-12-06 22:46:38 -08:00
Kubernetes Prow Robot
c16957fc8f Merge pull request #4908 from khrisrichardson/plugin/builtin/helmchartinflationgenerator/split
HelmChartInflationGenerator: split on yaml document end markers
2022-12-06 15:38:37 -08:00
Khris Richardson
03c1534c38 HelmChartInflationGenerator: split on yaml document end markers 2022-12-06 14:35:43 -08:00
Katrina Verey
903fbb6ed2 Wildcard support for creation in ReplacementTransformer (#4886)
* Ahead-of-time wildcard path expansion solution

* Wrapped PathGetter solution

This approach doesn't work when multiple existing sequence elements
should match, i.e. because the sequence contains maps and we're
searching on a key they all contain (target all containers with a certain
image would be one use case for this). PathGetter just takes the first
match in that case, which is not what we want.

* Add creation support to PathMatcher

* Regression test for existing bug when creation is enabled and sequence query should match multiple elements

* PathMatcher Create tests and support for sequence appending

* revert hyphen append support

PathGetter treats it as meaning 'last' not 'append' and does not have test coverage for its handling of this when create is set. Semantics are dubious given that multiple Replacement fieldPaths may be specified, which would cause successive appends.

* This also provides a solution to issue 1493

* Review feedback
2022-12-06 12:40:37 -08:00
Katrina Verey
2ed910abb0 Replacements should throw errors on invalid targets (#4789)
* Replacements should throw errors on invalid targets

* Refactor to satisfy complexity linter

* Move new tests to filter suite
2022-12-05 18:54:36 -08:00
Christopher Fry
570865baae Address peer review 2022-12-05 23:06:50 +00:00
Anna Song
71eb865cea Localize configMapGenerator, secretGenerator fields (#4894)
* Localize configMapGenerator, secretGenerator fields

* Improve readability

* Expose kv parseFileSource

* Add localizeGenerator to Localizer

* Improve and test ParseFileSource error messages
2022-12-02 15:31:53 -08:00
Yannis Zarkadas
a502717460 Make ordering configurable (#4019)
* api: Add new types for customizeable resource ordering

Signed-off-by: Yannis Zarkadas <yanniszark@arrikto.com>

* plugins: Implement SortOrderTransformer plugin

Implement the SortOrderTransformer plugin. This plugin allows the user
to customize the order that kustomize will output resources in.

The API for the plugin is the following:

sortOptions:
  order: legacy | fifo
  legacySortOptions:
    orderFirst:
    - {GVK}
    orderLast:
    - {GVK}

Signed-off-by: Yannis Zarkadas <yanniszark@arrikto.com>

* plugins: Add boilerplate and generate code for new SortOrderTransformer

Signed-off-by: Yannis Zarkadas <yanniszark@arrikto.com>

* build: Add option to denote if the reorder flag was set by the user

We want to take different actions if the reorder flag was set by the
user or filled by the default value. Thus, we propagate this information
from build to the krusty options.

Signed-off-by: Yannis Zarkadas <yanniszark@gmail.com>

* api/krusty: Ensure sort ordering works with CLI flag and kustomization

Sort order can be defined in two places:
- (new) kustomization file
- (old) CLI flag
We want the kustomization file to take precedence over the CLI flag.

Eventually, we may want to move away from having a CLI flag altogether:
https://github.com/kubernetes-sigs/kustomize/issues/3947

Case 1: Sort order set in kustomization file AND in CLI flag.
Print a warning and let the kustomization file take precedence.

Case 2: Sort order set in CLI flag only or not at all.
Follow the CLI flag (defaults to legacy) and reorder at the end.

Case 3: Sort order set in kustomization file only.
Simply build the kustomization.

Signed-off-by: Yannis Zarkadas <yanniszark@gmail.com>

* krusty: Add e2e test for SortOrderTransformer

Signed-off-by: Yannis Zarkadas <yanniszark@arrikto.com>

* plugins: Purge LegacyOrderTransformer

Signed-off-by: Yannis Zarkadas <yanniszark@gmail.com>

* Update go.work.sum

Signed-off-by: Yannis Zarkadas <yanniszark@gmail.com>

* review: Make review changes

Signed-off-by: Yannis Zarkadas <yanniszark@gmail.com>

Signed-off-by: Yannis Zarkadas <yanniszark@arrikto.com>
Signed-off-by: Yannis Zarkadas <yanniszark@gmail.com>
2022-12-02 13:59:53 -08:00
Kishore Jagannath
1e2e7bbc0b Refactor 7 return values in parseGitUrl to RepoSpec(issue 4866, Task1) (#4900)
* initial commit to refactor 7 return values in parseGitUrl to RepoSpec

* fix review comments
2022-12-02 10:01:53 -08:00
Anna Song
e34d5b5608 Localize components (#4867) 2022-12-02 09:33:53 -08:00
Kubernetes Prow Robot
0f4f978956 Merge pull request #4895 from KnVerey/remove-local-last
Remove local-only resources at the last minute
2022-12-01 13:20:00 -08:00
Kubernetes Prow Robot
663b777910 Merge pull request #4892 from KnVerey/issue_forms
Use Github forms for issue templates
2022-12-01 13:19:53 -08:00
Kubernetes Prow Robot
3c8db55f53 Merge pull request #4901 from annasong20/clean-localizer
Clean `localizer`
2022-12-01 11:21:54 -08:00
Anna Song
b8611cf0a9 Refactor localizer code
* encapsulate kusttarget params
* change dst to string
* ConfirmDir
2022-12-01 09:53:46 -08:00
Kubernetes Prow Robot
588da7e392 Merge pull request #4852 from pacoxu/psp-cleanup
remove PSP as v1.25 remove it
2022-11-30 08:44:55 -08:00
Kubernetes Prow Robot
baf777c56e Merge pull request #4893 from KnVerey/pluginator-linter-bug
Fix pluginator incompatibility with nolint lines
2022-11-30 08:32:55 -08:00
Katrina Verey
a612cd2b7e Fix pluginator incompatibility with nolint lines 2022-11-30 11:22:10 -05:00
Paco Xu
37ad9b1d4e remove PSP as v1.25 remove it 2022-11-30 10:16:39 +08:00
Katrina Verey
fb0f567b63 Remove local-only resources at the last minute
This allows name references to them to be correctly resolved
2022-11-29 19:05:16 -05:00
Kubernetes Prow Robot
f53d018302 Merge pull request #4885 from annasong20/contain-ldr-path
Contain `RepoSpec` path in repo
2022-11-29 14:35:08 -08:00
Kubernetes Prow Robot
d9d9785791 Merge pull request #4890 from brianpursley/kustomize-4628
merge2: preserve explicitly set null values
2022-11-29 12:35:08 -08:00
Katrina Verey
76fab6e7ba Use Github forms for issue templates 2022-11-28 18:17:55 -05:00
Anna Song
832b552076 Load built-in plugins for kustomize localize (#4869)
* Load and filter built-in plugins

* Improve readability

* Process plugins as resources instead of bytes

* Throw error for validators

* Differentiate generators, transformers processing

* Enable validators

* add wrapper error
* improve documentation
2022-11-28 13:23:42 -08:00
Anna Song
0eff094faf Calculate localized path for remote file (#4878)
* Calculate localized path for remote file

* Add documentation
2022-11-28 09:36:06 -08:00
Brian Pursley
1b7db20504 merge2: preserve explicitly set null values
Fixed bug where an explicitly set null value in yaml was
cleared, even when the patch did not operate on that field.
2022-11-26 16:33:14 -05:00
Claus F. Strasburger
adce67301b install_kustomize: support linux/aarch64, with fallback to old behavior (#4619)
* install_kustomize: support linux/aarch64, with fallback to old behavior

* shellcheck

* Comments from first review

* Comments from review

* Review comments: message consistency
2022-11-24 10:20:04 -08:00
Kubernetes Prow Robot
a6eb8e8ce8 Merge pull request #4887 from KnVerey/statik_removal
Get rid of statik and fix failing tests
2022-11-23 19:00:04 -08:00
Katrina Verey
7f9f6140ff Get rid of statik and fix failing tests 2022-11-23 20:34:38 -05:00
Anna Song
07063a2652 Prevent repoSpec path from exiting repo 2022-11-23 14:29:22 -08:00
Kubernetes Prow Robot
e5ab220821 Merge pull request #4868 from emirot/chore_upgrade_helm
chore: upgrade helm version
2022-11-21 18:26:13 -08:00
Christopher Fry
0c4f863bc5 Add test ensuring user configuration overrides default configuration 2022-11-21 23:39:45 +00:00
Kubernetes Prow Robot
78978723db Merge pull request #4840 from oscr/update-golangci-lint
Update golangci-lint version (1.49.0 -> 1.50.1) and enable linters: dupword and testableexamples
2022-11-17 10:36:29 -08:00
Kubernetes Prow Robot
8ea5eb22f1 Merge pull request #4877 from KnVerey/go_1.19
Update to Go 1.19
2022-11-17 10:18:40 -08:00
Katrina Verey
91a2c2b1a4 Update to Go 1.19 2022-11-17 12:57:17 -05:00
Natasha Sarkar
62f0dab2ac Merge pull request #4876 from KnVerey/new_token
Regenerate token and encrypt without newline (attempt 4)
2022-11-16 13:46:19 -06:00
Katrina Verey
d642b959cf Regenerate token and encrypt without newline 2022-11-16 14:36:33 -05:00
Natasha Sarkar
d49f6e17ad Merge pull request #4875 from KnVerey/new_token
Third try new token without newline
2022-11-16 13:25:32 -06:00
Katrina Verey
0de4e0ba11 Third try new token without newline 2022-11-16 14:24:20 -05:00
Natasha Sarkar
54569e4591 Merge pull request #4874 from KnVerey/token_again
New token, hopefully without trailing whitespace error
2022-11-16 13:12:49 -06:00
Katrina Verey
b2dc88447e New token, hopefully without trailing whitespace error 2022-11-16 14:11:40 -05:00
Anna Song
314b8fbefa Implement localizeFile() skeleton for patches (#4865)
* Implement localizeFile()

* Fix lint

* Address code review feedback

* Remove unnecessary String(), Error() with string formatters
* Remove processing of un-implemented methods
* Improve readability

* Remove unimplemented addLocalizeDir, hitsLocalizeDir

* Improve documentation

* Remove deprecated patchesJson6902 logic
2022-11-16 10:24:48 -08:00
Natasha Sarkar
c0840b6804 Merge pull request #4873 from KnVerey/new_token
Rotate token for cloud build
2022-11-16 10:58:14 -06:00
Katrina Verey
1eccbc4e30 Rotate token for cloud build 2022-11-16 11:54:33 -05:00
Anna Song
f79e16b352 Improve localizer readability (#4860)
* Replace '%s' with %q

* Change ambiguous cli-"Arg" suffix in func arg names

* Remove repetitive "loc" in names

* Apply readability changes to localizer

* Fix comment
2022-11-16 08:42:49 -08:00
Kubernetes Prow Robot
b20e611413 Merge pull request #4723 from koba1t/emit_a_warning_when_deprecated_fields_are_used
Emit a warning on build when deprecated fields are used
2022-11-16 08:32:50 -08:00
Kubernetes Prow Robot
e638e408b0 Merge pull request #4802 from oscr/the-the
grammar: replace all occurrences of "the the" with "the"
2022-11-16 08:22:48 -08:00
emirot
473c0a5f19 chore: upgrade helm version 2022-11-14 17:14:07 -08:00
Anna Song
84bd402cc0 Fix RepoSpec query extraction (#4863)
* Clean query processing

* Improve readability

* Remove redundant code
* Add comment

* Return path literal when not parsable

* Handle url.Parse() error in future
2022-11-14 09:38:41 -08:00
Kubernetes Prow Robot
e724e25fec Merge pull request #4855 from koba1t/chore/add_koba1t_to_reviews
add koba1t to reviews
2022-11-10 14:22:09 -08:00
Anna Song
50e731a1d9 Implement localizer skeleton for kustomize localize (#4859)
* Add localizer outline

* Add localizer unit tests

* include previous change

* Add proper NewLocalizer, Localize unit tests

mock processKust

* Address code review feedback

* Make processKustFn public

* Remove mock testing
2022-11-10 09:24:54 -08:00
Anna Song
beb2825f82 Improve readability of ifc.Loader's Repo() method (#4857)
* Improve ldr Repo() method readability

* Change Repo() implementations and calls

* Improve readability of conditions in ldr.New()

* Fix details
2022-11-08 14:48:14 -08:00
Anna Song
6d9b54004e Address TODO in PR #4652 (#4856)
* Address TODO in PR #4652

* Improve readability
2022-11-08 13:51:01 -08:00
yugo kobayashi
1f04fd2f23 add koba1t to reviews 2022-11-07 18:40:54 +00:00
Kubernetes Prow Robot
6ffd22a1f1 Merge pull request #4854 from koba1t/fix/failed_lint_on_master
fix: failed lint on master
2022-11-07 10:16:18 -08:00
yugo kobayashi
3e6ede9645 fix_failed_lint_on_master 2022-11-04 07:12:46 +00:00
Kubernetes Prow Robot
14f3cea24f Merge pull request #4830 from summer-dev/update-swagto-v0.22.3
update kyaml's dependency swag to v0.22.3
2022-11-03 21:06:14 -07:00
sun min
f0f414d53a e2econtainerconfig test failure 2022-11-04 10:34:37 +08:00
sun min
f9d553689e update dependencies of libs using go workspace mode 2022-11-02 13:44:23 +08:00
summer-dev
69435e059a Merge branch 'kubernetes-sigs:master' into update-swagto-v0.22.3 2022-11-02 09:46:51 +08:00
Oscar Utbult
e16b0f0dfc Update golangci-lint version (1.49.0 -> 1.50.1) and enable linters dupword and testableexamples 2022-10-31 19:31:56 +01:00
Natasha Sarkar
997e6fcc63 fix TestRemoteLoad_LocalProtocol (#4844)
* remote load test fix

* fix spacing
2022-10-31 10:58:44 -07:00
Kubernetes Prow Robot
daf81df437 Merge pull request #4654 from aabouzaid/fix-krm-exec-function
fix: krm exec function working dir
2022-10-26 11:30:36 -07:00
Ahmed AbouZaid
3e447da6ef proposal v2.1 2022-10-22 03:16:41 +02:00
Ahmed AbouZaid
ea21b37d67 proposal v2 2022-10-22 03:16:41 +02:00
Ahmed AbouZaid
d29febecb7 Fix krm exec function working dir 2022-10-22 03:16:41 +02:00
Ahmed AbouZaid
1b1e6ccab0 Test transformers krm exec function 2022-10-22 03:16:41 +02:00
Kubernetes Prow Robot
7ee6dd551d Merge pull request #4733 from koba1t/feat/add_edit-fix_for_patchesStrategicMerge_to_patches
add `edit fix` for patchesStrategicMerge to patches
2022-10-21 14:57:57 -07:00
Kubernetes Prow Robot
ccb68aa881 Merge pull request #4820 from florianl/flo-preallocate
preallocate memory
2022-10-21 14:35:57 -07:00
sun min
1252e45576 update kyaml's go.mod and go.sum 2022-10-13 09:34:45 +08:00
summer-dev
19d163ca0f update kyaml's dependency swag to v0.22.3 2022-10-12 21:30:12 +08:00
Kubernetes Prow Robot
bf7a0f9004 Merge pull request #4805 from aibarbetta/fix-4717
[address #4717] Re-do create template/metadata when using includeTemplates if not present
2022-10-11 09:23:02 -07:00
Kubernetes Prow Robot
3b1a711cee Merge pull request #4826 from dvrkps/patch-1
update actions/checkout
2022-10-11 09:13:01 -07:00
Davor Kapsa
cd35e95560 update actions/checkout 2022-10-11 11:41:21 +02:00
Kubernetes Prow Robot
0a16b6cf40 Merge pull request #4808 from larsks/feature/no-hooks
Add support for helm --no-hooks flag
2022-10-10 11:51:22 -07:00
Agustina Barbetta
7b84613ad1 Use fewer labels to ease reading 2022-10-08 20:38:44 -03:00
Agustina Barbetta
d14dfb604c Use WrapPrefixf 2022-10-08 20:37:24 -03:00
Agustina Barbetta
acba8fff62 Update api/krusty/inlinelabels_test.go
Co-authored-by: Katrina Verey <kn.verey@gmail.com>
2022-10-08 20:18:57 -03:00
Lars Kellogg-Stedman
38da7ca15c Add support for helm --no-hooks flag
This commit adds the `skipHooks` option to the helm chart support in order
to  expose the --no-hooks flag introduced to Helm in [1].

Using Kustomize to inflate a Helm chart would in some situations result in
different results than using `helm install`. This is because `helm
template`, by default, will render chart tests in the `templates/test`
directory, which can lead to undesired resources in the output.

See [2] for additional discussion.

[1]: https://github.com/helm/helm/pull/6444
[2]: https://github.com/helm/helm/issues/6443

Signed-off-by: Lars Kellogg-Stedman <lars@oddbit.com>
2022-10-07 17:14:06 -04:00
Kubernetes Prow Robot
9ef7ba9c95 Merge pull request #4663 from johnmanjiro13/handle-error-of-remove-annotation
fix: handle error of remove annotations
2022-10-07 08:19:53 -07:00
johnmanjiro13
4e7f4bce7b feat: Wrap error 2022-10-07 18:14:59 +09:00
Kubernetes Prow Robot
f8f444d92a Merge pull request #4819 from annasong20/add-reviewer
Add annasong20@ to reviewers list
2022-10-06 09:23:54 -07:00
Florian Lehner
c2312c4018 kyaml/yaml: preallocate memory
Signed-off-by: Florian Lehner <dev@der-flo.net>
2022-10-06 05:38:18 +02:00
Florian Lehner
0fbaa2d0e8 kyaml/sets: preallocate memory
Signed-off-by: Florian Lehner <dev@der-flo.net>
2022-10-06 05:37:41 +02:00
Anna Song
ae20497fd3 Add myself to reviewers list 2022-10-05 16:16:10 -07:00
Dani Santos
506dc4f9fe migrate site content: contributing docs (#4709)
* migrate contributing docs

* modifies weight for ordering

* updates links and info based on feedback

* removes broken powershell link

* Update site/content/en/contribute/windows/_index.md

Co-authored-by: Katrina Verey <kn.verey@gmail.com>

* Update site/content/en/contribute/windows/_index.md

Co-authored-by: Katrina Verey <kn.verey@gmail.com>

* Update site/content/en/contribute/mac/_index.md

Co-authored-by: Katrina Verey <kn.verey@gmail.com>

* Update site/content/en/contribute/howitworks/_index.md

Co-authored-by: Katrina Verey <kn.verey@gmail.com>

* Update site/content/en/contribute/howitworks/_index.md

Co-authored-by: Katrina Verey <kn.verey@gmail.com>

* simplify build explanation

* removes windows docs

* removes community - duplicate

* update the tooling instructions

* point to proposal docs

* Update site/content/en/contribute/howitworks/_index.md

Co-authored-by: Katrina Verey <kn.verey@gmail.com>
2022-09-29 10:20:39 -07:00
Kubernetes Prow Robot
482e8930fc Merge pull request #4809 from ephesused/issue-4793
convert PrevIds to use apiVersion instead meta
2022-09-27 14:21:50 -07:00
Ed Overton
d37fabf876 convert PrevIds to use apiVersion instead meta
Since PrevIds uses only the apiVersion information from the metadata,
change the retrieval from the full meta to just the apiVersion.
2022-09-27 14:03:59 -04:00
Agustina Barbetta
eb1529b516 use %w to format errors 2022-09-25 09:19:31 -03:00
Agustina Barbetta
c750c0089d use fmt instead of errors 2022-09-25 09:07:47 -03:00
Agustina Barbetta
2b9ef61f88 error wraps for linter 2022-09-23 18:30:00 -03:00
Agustina Barbetta
344b257c1f add tests for other kinds 2022-09-23 15:54:25 -03:00
Agustina Barbetta
e2196d9bd1 separate template specific field specs and use in includeTemplates 2022-09-23 15:11:59 -03:00
Kubernetes Prow Robot
65aeefd281 Merge pull request #4806 from koba1t/chore/update_golangci-lint_v1.49.0
update golangci-lint version to v1.49.0
2022-09-23 10:00:26 -07:00
yugo kobayashi
6ce230f2b2 fix testcases on runfn_test.go 2022-09-23 07:26:19 +00:00
yugo kobayashi
401cf9579c update golangci-lint v1.49.0 2022-09-22 13:24:40 +00:00
Agustina Barbetta
4dcc040ec1 create template/metadata in includeTemplates if not present 2022-09-20 13:33:07 -03:00
Agustina Barbetta
662ccf1915 add test for resources with no template 2022-09-20 13:29:38 -03:00
Yunchi Luo
e62480d11c Rewrite remoteload_test integration tests (#4783)
* Better error message when git clone fails

* support file:// URLs

* rewrite remoteload_test

* lint and test fix

* fixes for kverey's comments

* document file:// remote load

* replace assert with require where appropriate

* add tests for file:// without git suffix

* fixes plus pr review from natasha

* fixes for review, lint

* revert changes to error handling

* fix skipped test
2022-09-19 09:13:18 -07:00
Oscar Utbult
88cf251ef7 grammar: replace all occurrences of "the the" with "the" 2022-09-17 22:28:56 +02:00
Kubernetes Prow Robot
d6e40a3f6c Merge pull request #4798 from annasong20/patch-1
Fix flaky
2022-09-16 10:23:21 -07:00
Anna Song
eb51117adf Fix flaky
Disable submodules and increase timeout to prevent `localize` test that uses testdata from flaking.
2022-09-15 18:05:25 -07:00
yugo kobayashi
0d68e0c7be add newline for fix.go 2022-09-12 17:56:11 +00:00
yugo kobayashi
7c2e8845ad fix test with t.Run() 2022-09-12 17:47:33 +00:00
Kubernetes Prow Robot
ce18530656 Merge pull request #4791 from caproven/fix-4790
Performance fix for fetching previous resource IDs
2022-09-12 09:51:25 -07:00
Christian Provenzano
ca71736140 Wrap error in exported func 2022-09-09 20:27:28 -04:00
Christian Provenzano
e7d5f665b8 Fix redundant rnode metadata parsing 2022-09-09 19:25:59 -04:00
Kubernetes Prow Robot
6c587c9542 Merge pull request #4770 from jihoon-seo/220824_Fix_broken_links
Fix broken links
2022-09-09 08:49:22 -07:00
Kubernetes Prow Robot
56a47bd901 Merge pull request #4758 from koba1t/feature/emit_a_warning_to_ignore_plugin
Emit a warning when using missing field in FunctionSpec
2022-09-09 08:35:23 -07:00
johnmanjiro13
a8c0be49ae fix: handle error of remove annotations 2022-09-05 16:27:59 +09:00
yugo kobayashi
e49bf52928 fix tests 2022-09-03 00:29:10 +00:00
yugo kobayashi
a54226e0a9 fix error handling 2022-09-03 00:29:10 +00:00
yugo kobayashi
f086269d6e be build fail when parse failed to FunctionSpec 2022-09-03 00:29:10 +00:00
yugo kobayashi
e2e9181bed add a warning to missing field in FunctionSpec 2022-09-03 00:29:10 +00:00
yugo kobayashi
21ee7f7125 Emit a warning when deprecated fields are used 2022-09-01 23:02:50 +00:00
yugo kobayashi
cbb61fc668 fix yaml in test 2022-09-01 22:41:24 +00:00
Kubernetes Prow Robot
23de1499c2 Merge pull request #4719 from oscr/remove-dot-from-short
Remove dots from short descriptions
2022-08-30 09:54:55 -07:00
Kubernetes Prow Robot
cb2636335f Merge pull request #4779 from annasong20/locloader
Reinstate #4652 without url-related code
2022-08-30 08:13:01 -07:00
Kubernetes Prow Robot
c266537b27 Merge pull request #4777 from mightyguava/repospec-unit-tests
expand and clean up repospec_test
2022-08-29 18:11:03 -07:00
Anna Song
f80cf9f433 Reinstate #4652 without url-related code
Remove code that changes remotes-loading code path, as mandated by #4756
2022-08-29 16:57:15 +00:00
yugo kobayashi
032bf3338e update checker code in patchStrategicMerge 2022-08-28 17:20:21 +00:00
yugo kobayashi
b4d25b1b26 add testcases 2022-08-28 15:45:47 +00:00
Yunchi Luo
d917876949 expand and clean up repospec_test 2022-08-27 14:30:10 -04:00
Kubernetes Prow Robot
14b7282ed8 Merge pull request #4775 from kubernetes-sigs/revert-4652-localize-file
Revert "Load and calculate Destination of files for `kustomize localize`"
2022-08-26 11:48:16 -07:00
Natasha Sarkar
8868d91670 Revert "Load and calculate Destination of files for kustomize localize (#4652)"
This reverts commit bf17fe1d8f.
2022-08-26 13:26:23 -05:00
Kubernetes Prow Robot
b6fae2a959 Merge pull request #4759 from mightyguava/enable-ssh-tests
Enable SSH tests
2022-08-26 09:14:25 -07:00
Kubernetes Prow Robot
a8388f473b Merge pull request #4773 from natasha41575/openapitests
run openapi tests with other krusty tests
2022-08-26 08:36:24 -07:00
natasha41575
08918ea352 run openapi tests with other krusty tests 2022-08-26 09:01:44 -05:00
Yunchi Luo
5dcbd35e40 Enable SSH tests 2022-08-25 16:57:21 -04:00
Kubernetes Prow Robot
2e2674fa24 Merge pull request #4727 from KnVerey/improve_fieldspec_errors
Improve invalid node kind errors
2022-08-25 12:44:07 -07:00
Jihoon Seo
170eca7c52 Fix broken links 2022-08-24 17:25:29 +09:00
Anna Song
bf17fe1d8f Load and calculate Destination of files for kustomize localize (#4652)
* Implement file localization for localize

Implement file localization for new command kustomize localize

* Patch file localization

Fix lint errors, address feedback, begin transition to file loader from
localizer

* Add Repo() to Loader

* Implement locLoader factory + cleanup

* Add domain to RepoSpec

Fix ssh relative url host parsing for non-github domain on the side

* Implement Load(), New(), Root(), Dst() for LocLoader

* Address repospec code review comments

* Address 1st round of code review feedback

* Address feedback #2

Removed localized path calculations to cover edge case and improve readability.

* Remove ldr Cleanup logging

* Address code review round #3

* Address code review feedback #4
2022-08-19 14:33:53 -07:00
Natasha Sarkar
a8010ac469 Merge pull request #4764 from KnVerey/update_go_yaml
Update internal go-yaml fork to v3.0.1
2022-08-17 16:45:50 -05:00
Katrina Verey
f66936f6bf Internalize forked code 2022-08-17 16:09:05 -04:00
Natasha Sarkar
eb54c97947 fix leading newline issue 2022-08-17 16:09:05 -04:00
Natasha Sarkar
b84885d5c4 tests for compactSeqIndent 2022-08-17 16:09:04 -04:00
Natasha Sarkar
298d977ee7 add defaultSeqIndent method 2022-08-17 16:09:04 -04:00
Natasha Sarkar
d5a2009d3f compact sequence indentation option 2022-08-17 16:09:04 -04:00
Katrina Verey
d0ae8fba13 Internal copy of go-yaml at f6f7691b1fdeb513f56608cd2c32c51f8194bf51 2022-08-17 16:09:03 -04:00
Katrina Verey
f8d1e778c7 Commit go.sum updates 2022-08-16 18:26:04 -04:00
Katrina Verey
1948af8190 Wrap an error and remove a nolint 2022-08-16 18:24:20 -04:00
Katrina Verey
79a9154cf8 Improve error message when namespace transformer is given invalid fieldspecs
Also remove invalid+ignored fieldspecs from the defaults
2022-08-16 18:18:44 -04:00
Robert Facciol
26fcafdb57 Getting started guide part 2 (#4748)
* rename overlays

* add further examples in first kustomization

* fix typo

* fix formatting

* fix typo

* fix formatting

* fix typos

* restore overlay names to production and staging in original content

* restore overlay names to production and staging in original content

* restore overlay names to production and staging in new content

* updated doc to use "you/your" vs "we/our", and updated to use US spelling

* fix capitalization

* Update site/content/en/docs/Getting started/first_kustomization.md

Co-authored-by: Katrina Verey <kn.verey@gmail.com>

* Update site/content/en/docs/Getting started/first_kustomization.md

Co-authored-by: Katrina Verey <kn.verey@gmail.com>

* add "patch:" for patches in kustomization, and add url link

* Update site/content/en/docs/Getting started/first_kustomization.md

Co-authored-by: Katrina Verey <kn.verey@gmail.com>

* fix typo

Co-authored-by: Katrina Verey <kn.verey@gmail.com>
2022-08-16 11:11:08 -07:00
Kubernetes Prow Robot
2ec4b971e9 Merge pull request #4754 from KnVerey/ioutil
Stop using deprecated ioutil functions
2022-08-16 09:15:08 -07:00
Kubernetes Prow Robot
1d44793d79 Merge pull request #4648 from sklirg/fix/example-readme-install-url
docs(examples): Fix URL to installation instructions in examples
2022-08-12 15:42:30 -07:00
Katrina Verey
55a37de686 Fix other linters on modified lines 2022-08-10 19:34:25 -04:00
Katrina Verey
f6b72077c8 Stop using deprecated ioutil functions 2022-08-10 18:22:46 -04:00
Katrina Verey
416eed97c4 Merge pull request #4753 from kubernetes-sigs/revert-4751-fix-4717
Revert "[address #4717] create template/metadata when using includeTemplates if not present"
2022-08-10 14:35:28 -04:00
Katrina Verey
5762794793 Revert "[address #4717] create template/metadata when using includeTemplates if not present" 2022-08-10 14:06:33 -04:00
Kubernetes Prow Robot
91e002a560 Merge pull request #4751 from aibarbetta/fix-4717
[address #4717] create template/metadata when using includeTemplates if not present
2022-08-10 11:00:26 -07:00
Agustina Barbetta
15545cc228 create template/metadata in includeTemplates if not present 2022-08-07 20:48:51 -03:00
yugo kobayashi
3f0c21304c refactor edit fix test cases 2022-08-06 20:34:16 +00:00
yugo kobayashi
bb7ebe029c support file path patch to patchesStrategicMerge 2022-08-06 20:28:48 +00:00
yugo kobayashi
64f42ea45f add edit-fix for patchesStrategicMerge to patches 2022-08-06 20:28:48 +00:00
Natasha Sarkar
1b0fe2a078 update openapi scripts to fetch protobuffer schemas (#4582)
* update openapi scripts to fetch protobuffer schema

* code review

* code review

* restore makeOpenApiInfoDotGo.sh

* code review
2022-08-05 15:00:32 -07:00
Natasha Sarkar
56d82a8378 Merge pull request #4745 from natasha41575/pinToApi
pin to api v0.12.1
2022-08-02 11:28:01 -05:00
natasha41575
39dbdddb86 pin api to v0.12.1 2022-08-02 11:18:51 -05:00
Natasha Sarkar
27a1de1a19 Merge pull request #4744 from natasha41575/pinToCmdConfig
pin to cmd/config 0.10.9
2022-08-02 10:52:46 -05:00
natasha41575
7229f5fbed pin to cmd/config 0.10.9 2022-08-02 10:46:18 -05:00
Natasha Sarkar
ba9d5ee16f Merge pull request #4743 from natasha41575/PinToKyaml
Pin to kyaml v0.13.9
2022-08-02 10:37:42 -05:00
natasha41575
001b0c5fe5 pin to kyaml v0.13.9 2022-08-02 10:20:35 -05:00
Natasha Sarkar
bbeff6ddd6 prevent testing lib from being compiled in (#4742)
* remove testing dep from fsondisk

* code review
2022-08-01 14:26:29 -07:00
Kubernetes Prow Robot
e57b5d283f Merge pull request #4739 from natasha41575/updateReleaseNum
update latest release number to 4.5.6
2022-07-29 14:21:12 -07:00
natasha41575
dbd719bd3f update latest release number to 4.5.6 2022-07-29 16:05:15 -05:00
Natasha Sarkar
29ca6935bd Merge pull request #4738 from natasha41575/pinToApi
pin to api v0.12.0
2022-07-29 15:32:26 -05:00
natasha41575
f5c70b3929 pin to api v0.12.0 2022-07-29 15:23:05 -05:00
Natasha Sarkar
b816903c93 Merge pull request #4737 from natasha41575/pinCmdConfig
pin cmd/config 0.10.8
2022-07-29 15:13:29 -05:00
natasha41575
d32fe662af pin cmd/config 0.10.8 2022-07-29 15:06:34 -05:00
Natasha Sarkar
4b5fbf2b80 Merge pull request #4736 from natasha41575/pinToKyaml
pin to kyaml v0.13.8
2022-07-29 14:51:55 -05:00
Kubernetes Prow Robot
283f8ae0a5 Merge pull request #4735 from natasha41575/statik
update statik
2022-07-29 12:47:12 -07:00
natasha41575
f6a1e4af3b pin to kyaml v0.13.8 2022-07-29 14:44:06 -05:00
Katrina Verey
e7fe132df8 Update netlify config (#4732)
* Update netlify config

* Update site/netlify.toml
2022-07-29 12:33:13 -07:00
natasha41575
631f623d9c update statik 2022-07-29 14:30:18 -05:00
Kubernetes Prow Robot
19c467a924 Merge pull request #4734 from natasha41575/goSum
update go.sum files
2022-07-29 11:51:13 -07:00
natasha41575
afa2b52807 merge go.sum files 2022-07-29 13:42:32 -05:00
Kubernetes Prow Robot
30843e2dac Merge pull request #4730 from KnVerey/env_bug_warning
Emit a warning when env loading bug is being relied on
2022-07-28 15:33:12 -07:00
Katrina Verey
2a3b645758 Emit a warning when env loading bug is being relied on 2022-07-28 18:04:48 -04:00
Kubernetes Prow Robot
b89cb92c2d Merge pull request #4729 from natasha41575/colonInFSName
allow colon in filenames
2022-07-28 13:13:11 -07:00
natasha41575
9a6aad3ae4 allow colon in filenames 2022-07-28 14:52:28 -05:00
Kubernetes Prow Robot
c4b4a41913 Merge pull request #4704 from KnVerey/ns_transformer_options
Option to customize NamespaceTransformer role binding subject handling
2022-07-28 08:27:11 -07:00
Katrina Verey
0c37ee89af Option to customize NamespaceTransfomer role binding subject handling 2022-07-27 23:12:55 -04:00
Kubernetes Prow Robot
6917214251 Merge pull request #4726 from AlexVulaj/update-install-kustomize-error-message
Update error message for m1 mac users trying to fetch older versions
2022-07-27 12:03:53 -07:00
Alex Vulaj
a3a3140e4c Update hack/install_kustomize.sh
update error message to be more descriptive

Co-authored-by: Natasha Sarkar <natashasarkar@google.com>
2022-07-27 14:30:07 -04:00
Alex Vulaj
d244c8a8bb Update error message for m1 mac users trying to fetch older versions 2022-07-27 13:54:04 -04:00
Oscar Utbult
d96e47cc38 Remove dots from short descriptions 2022-07-22 17:33:24 +02:00
Natasha Sarkar
2f2ba40876 replacements: fix issue with create: true option when there is an existing field (#4667)
* replacements: demonstrate broken behavior when using 'create: true' with an already existing field

* replacements: fix issue with 'create: true' option when there is an existing field

* Suggestion for PR 4667

* code review

* lint error

Co-authored-by: Katrina Verey <katrina.verey@shopify.com>
2022-07-15 14:31:49 -07:00
Kubernetes Prow Robot
ab09d27ec7 Merge pull request #4711 from koba1t/fix/docker_build_post-kustomize-push-images_with_dockerignore
[fix] failed docker build on post-kustomize-push-images CI
2022-07-14 14:00:40 -07:00
yugo kobayashi
5e95c6ab06 delete ./functionsfor .dockerignore 2022-07-14 20:35:25 +00:00
Katrina Verey
0c6e827ab8 Option to customize NamespaceTransformer overwrite behaviour (#4708)
* Option to customize NamespaceTransformer overwrite behaviour

* Code review feedback
2022-07-14 12:00:58 -07:00
Kubernetes Prow Robot
17cbd96667 Merge pull request #4705 from natasha41575/gowork
update release tools for go workspace mode
2022-07-11 17:56:51 -07:00
Kubernetes Prow Robot
0fce7d53a9 Merge pull request #4703 from KnVerey/name-ref-annotations
Fix NameReference transformer handling of self-references in annotations
2022-07-11 17:22:50 -07:00
Katrina Verey
68780b4c0c Fix flakey test 2022-07-11 20:03:13 -04:00
Katrina Verey
04e1663b70 appendCsVAnnotation must mutate the annotations RNode in place
Otherwise, it is incompatible with filters like fieldSpec.Filter that recurse through a tree of RNodes. In the case of the bug this commit fixes, the leaf RNode is a metadata.annotation value field, and appendCsvAnnotation is called immediately before updating that leaf's value. If appendCsvAnnotation replaces the entire metadata.annotation RNode on the resource, the leaf RNode that gets updated is no longer attached to the resource.

Alternatively, `func (f Filter) setScalar` could be updated to change
the value of the leaf RNode BEFORE calling appendCsvAnnotation. However,
the modification of the entire metadata segment of the RNode in a
function that nominally just edits an annotation feels like a
side-effect prone to creating other difficult-to-debug situations,
beyond this ordering dependency.
2022-07-11 19:58:49 -04:00
natasha41575
ba77fd5b7f update release tools for go workspace mode 2022-07-11 10:34:08 -07:00
Katrina Verey
77814ac12b NameReferenceTransformer misses self references in annotations 2022-07-08 22:07:15 -04:00
Kubernetes Prow Robot
e1b6aa393a Merge pull request #4692 from koba1t/chore/add_support_for_go_workspace_mode
[proposal] add support for go workspace mode
2022-07-08 10:29:47 -07:00
yugo kobayashi
3229c810cc restore require sigs.k8s.io/kustomize/* in go.mod 2022-07-08 16:58:01 +00:00
Kubernetes Prow Robot
344d0eec83 Merge pull request #4700 from KnVerey/ns_transformer_err_on_ambiguous_ns
Correctly detect ambiguity between potential referrers when targeting a name+namespace reference
2022-07-07 15:48:37 -07:00
Katrina Verey
387c95be1f Correctly detect ambiguity between potential referrers when targeting a name+namespace reference 2022-07-07 18:33:48 -04:00
yugo kobayashi
c02d0e502a go work sync 2022-07-07 21:00:43 +00:00
yugo kobayashi
5806c6f4f7 Merge remote-tracking branch 'origin' into chore/add_support_for_go_workspace_mode 2022-07-07 20:54:10 +00:00
yugo kobayashi
396b693e1c fix from lint error 2022-07-07 20:35:27 +00:00
Kubernetes Prow Robot
f95ea9e6a0 Merge pull request #4699 from koba1t/chore/update_go_1.18
Update to go 1.18
2022-07-07 13:32:38 -07:00
yugo kobayashi
8c4d35470a restore cloudbuild.yaml 2022-07-07 20:25:52 +00:00
yugo kobayashi
6fb96b7d53 update go 1.18 2022-07-07 20:11:29 +00:00
Kubernetes Prow Robot
ca01b49614 Merge pull request #4698 from koba1t/chore/update_functions_examples_and_e2econtainerconfig
Update kyaml in functions/examples and e2econtainerconfig
2022-07-07 12:28:38 -07:00
yugo kobayashi
4653f5d9d3 update e2econtainerconfig 2022-07-07 18:56:50 +00:00
yugo kobayashi
bd67fc2781 update kyaml in functions/examples 2022-07-07 18:51:12 +00:00
yugo kobayashi
17af5d518f rerun ci 2022-07-07 18:39:38 +00:00
yugo kobayashi
670cef4fd1 remove 'replace sigs.k8s.io/kustomize/*' and cleanup 2022-07-07 18:30:49 +00:00
yugo kobayashi
5c9adf248c fix error handling and delete comment to e2econtainerconfig/main.go 2022-07-07 16:10:14 +00:00
yugo kobayashi
fd847108cd refactor cmd/config/internal/commands/e2e 2022-07-06 16:03:47 +00:00
Kubernetes Prow Robot
d2ceab5f30 Merge pull request #4689 from Chever-John/doc/typo_error_first_kustomization
doc(first_kustomization): change the wrong command (I think)
2022-07-05 10:59:20 -07:00
Anna Song
86a84ca486 Address nits on localize proposal and correct mistakes (#4668)
* Address nits on #4590 and correct mistakes

* Flesh out remote target use case

Remove scope, add ref, add user story
2022-07-05 10:51:20 -07:00
yugo kobayashi
876ec8fa6b update to go 1.18 in github-action 2022-07-05 17:40:44 +00:00
yugo kobayashi
2145d1984f add missing test case 2022-07-05 02:53:32 +00:00
koba1t
92288a8a02 fix ci error 2022-07-05 06:40:30 +09:00
koba1t
a6449aa03f try to fix e2econtainer test 2022-07-05 03:44:56 +09:00
koba1t
9c827f5362 restore ./cmd/config/internal/commands/e2e/e2econtainerconfig 2022-07-02 15:54:48 +09:00
koba1t
e201dbb31a go work sync 2022-07-02 15:31:24 +09:00
koba1t
bc981fcbc3 merge upstream master 2022-07-02 15:18:26 +09:00
Kubernetes Prow Robot
8a729459aa Merge pull request #4694 from annasong20/add-loc-tdata-remote
Add `localize` test data with remote reference
2022-06-30 14:22:44 -07:00
Anna Song
d1102fb726 Move demandDirectoryRoot into kyaml/filesys (#4677)
* Move demandDirectoryRoot into kyaml/filesys

* Make root directory platform-agnostic

Support windows root directory. Dogfood own error package.

* Use cleaner windows support implementation

* Address feedback

* Address feedback x2

* Re-apply go.sum changes to avoid CI errors
2022-06-30 11:12:07 -07:00
Anna Song
edb6294741 Add kustomization with remote reference 2022-06-30 17:21:23 +00:00
koba1t
175c99f9f6 try to update cmd/config/internal/commands/e2e/e2econtainerconfig code 2022-06-30 05:06:34 +09:00
koba1t
20a93fdd12 update functions/examples/template-go-nginx code and update go1.18 2022-06-30 03:05:00 +09:00
koba1t
0421c9fb50 update functions/examples/injection-tshirt-sizes code 2022-06-30 01:48:58 +09:00
koba1t
8c8a2125b7 update all go.mod to go1.18 2022-06-29 05:14:33 +09:00
koba1t
f39f914a98 add many pkgs for go.work 2022-06-29 03:32:54 +09:00
koba1t
c583f4164c add support for go workspace mode 2022-06-28 23:42:56 +09:00
CheverJohn
6a7cecddd7 doc(first_kustomization): change the wrong command (I think) 2022-06-27 12:05:56 +08:00
Nuno Anselmo
d8efc15169 Adds commentary on expected/unexpected test output 2022-06-21 23:52:39 +01:00
Nuno Anselmo
86d48b2a95 Implements TestNamedspacedServiceAccounts with and without overlap 2022-06-21 23:07:54 +01:00
Davanum Srinivas
7e0fd02783 Switch github.com/xlab/treeprint to release tag : v1.1.0 (#4675)
* Switch github.com/xlab/treeprint to release tag : v1.1.0

Signed-off-by: Davanum Srinivas <davanum@gmail.com>

* fix test to reflect changes in the dependency

Signed-off-by: Davanum Srinivas <davanum@gmail.com>
2022-06-10 14:33:46 -07:00
Kubernetes Prow Robot
1c53932166 Merge pull request #4670 from prasadkatti/patch-1
Update broken links to glossary terms
2022-06-08 11:36:00 -07:00
Prasad Katti
721a905e13 Update broken links to glossary terms 2022-06-08 11:13:34 -07:00
Anna Song
3fdf88d10e Allow tests to only run locally (#4664)
* Allow tests to only run locally

Allow tests that are flaky or currently unsupported on the server to run locally

* Address feedback
2022-06-08 10:04:23 -07:00
Kubernetes Prow Robot
4b19643b36 Merge pull request #4661 from annasong20/fileloader-require
fileloader_test: Replace lengthy t.Fatalf with require
2022-06-01 16:35:48 -07:00
Anna Song
b0b6c962dc Replace lengthy t.Fatalf with require 2022-06-01 17:46:30 -04:00
Kubernetes Prow Robot
78191b45fb Merge pull request #4611 from unrolled/unrolled-4338-overview-and-installation
Migrate site content: overview and installation
2022-06-01 08:47:07 -07:00
Natasha Sarkar
37a403fc65 Merge pull request #4650 from natasha41575/releaseUpdate
unpin modules and update latest release to 4.5.5
2022-05-23 20:11:27 +00:00
natasha41575
fd7e170b69 unpin modules and update latest release to 4.5.5 2022-05-23 12:47:59 -07:00
Håkon Solbjørg
afc1815f3f docs(examples): Fix URL to installation instructions in examples 2022-05-23 12:06:04 +02:00
Natasha Sarkar
daa3e5e2c2 Merge pull request #4647 from natasha41575/increase_cpu
increase vm size for cloud build
2022-05-20 20:21:22 +00:00
natasha41575
12adc1ff95 increase vm size for cloud build 2022-05-20 13:20:58 -07:00
Natasha Sarkar
41283c4727 Merge pull request #4646 from natasha41575/pinToApi
Update api to v0.11.5
2022-05-20 19:34:52 +00:00
natasha41575
30740f87f1 Update api to v0.11.5 2022-05-20 12:26:43 -07:00
Cory Jacobsen
2e036c24c2 Migrate site content: overview and installation 2022-05-13 19:53:38 +00:00
koba1t
7aa33ff471 add edit add labels command add option for labels without selector 2022-02-24 09:49:31 +09:00
707 changed files with 69718 additions and 81288 deletions

View File

@@ -1,7 +1,6 @@
.github
docs
examples
functions
hack
site
travis

View File

@@ -1,68 +0,0 @@
---
name: Bug report
about: Create a report to help us improve
title: ""
labels:
- kind/bug
assignees: ""
---
<!--
Please read this page: https://kubectl.docs.kubernetes.io/contributing/kustomize/bugs/ before
filing a bug
-->
<!-- Feel free to skip the sections if they are not applicable. -->
**Describe the bug**
<!-- A clear and concise description of what the bug is. -->
**Files that can reproduce the issue**
<!--
We cannot figure out or fix the issue if we don't know how to reproduce. Please
provide a minimum set of files that can reproduce the issue. You can paste the
file contents here or provide a link to a tarball or git repo.
Example:
kustomization.yaml
```
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
...
```
resources.yaml
```
apiVersion: v1
kind: Deployment
...
```
...
-->
**Expected output**
<!-- What's the expected output? -->
**Actual output**
<!-- What's the actual output? -->
**Kustomize version**
<!-- Please use the latest version when it's possible. -->
**Platform**
<!-- Linux/macOS/Windows? -->
**Additional context**
<!-- Add any other context about the problem here. -->

87
.github/ISSUE_TEMPLATE/bug_report.yaml vendored Normal file
View File

@@ -0,0 +1,87 @@
name: Bug report
description: File a bug report
labels: ["kind/bug"]
body:
- type: textarea
id: problem
attributes:
label: What happened?
description: |
Please provide as much info as possible. Not doing so may result in your bug not being addressed in a timely manner.
If this matter is security related, please disclose it privately via https://kubernetes.io/security
validations:
required: true
- type: textarea
id: expected
attributes:
label: What did you expect to happen?
validations:
required: true
- type: textarea
id: repro-files
attributes:
label: How can we reproduce it (as minimally and precisely as possible)?
description: Please provide a minimum set of files that can reproduce the issue. You can paste the file contents here or provide a link to a tarball or git repo. Even better, submit a tests case in the api/krusty package! For more information on how to do that, see https://kubectl.docs.kubernetes.io/contributing/kustomize/bugs/.
value: |
```yaml
# kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- resources.yaml
```
```yaml
# resources.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: test-object
data:
placeholder: data
```
validations:
required: true
- type: textarea
id: expected-output
attributes:
label: Expected output
description: If you are able to provide reproduction files, please include the output you expect here.
value: |
```yaml
```
validations:
required: false
- type: textarea
id: actual-output
attributes:
label: Actual output
description: If you are able to provide reproduction files, please include the output they currently produce here.
value: |
```yaml
```
validations:
required: false
- type: input
id: kustomize-version
attributes:
label: Kustomize version
description: Please use the latest version whenever possible.
placeholder: What version of Kustomize are you using?
validations:
required: true
- type: dropdown
id: os
attributes:
label: Operating system
options:
- Linux
- MacOS
- Windows
- Other
validations:
required: false

View File

@@ -1 +0,0 @@
blank_issues_enabled: true

6
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@@ -0,0 +1,6 @@
contact_links:
- name: Support request
url: https://discuss.kubernetes.io
about: |
Please do not submit support requests or questions as issues.
Ask your question in the Kubernetes Community Forums, or in the #kustomize channel on Kubernetes Slack (https://slack.k8s.io).

View File

@@ -1,26 +0,0 @@
---
name: Feature request
about: Suggest an idea for this project
title: ""
labels:
- kind/feature
assignees: ""
---
<!-- Feel free to skip the sections if they are not applicable. -->
**Is your feature request related to a problem? Please describe.**
<!-- A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] -->
**Describe the solution you'd like**
<!-- A clear and concise description of what you want to happen. -->
**Describe alternatives you've considered**
<!-- A clear and concise description of any alternative solutions or features you've considered. -->
**Additional context**
<!-- Add any other context or screenshots about the feature request here. -->

View File

@@ -0,0 +1,64 @@
name: Feature request
description: Propose an enhancement to Kustomize
labels: kind/feature
body:
- type: markdown
attributes:
value: |
Small, straightforward enhancements can be proposed in regular GitHub issues using the template below. As a rule of thumb, the enhancement should be resolvable in a single PR that is at most size L. Anything more involved requires a mini (in-repo) enhancement proposal, and features with implications for kubectl require a full [KEP](https://github.com/kubernetes/enhancements).
For more information on the Kustomize enhancement process, see: https://github.com/kubernetes-sigs/kustomize/tree/master/proposals.
When in doubt, go ahead and fill out the template below; the maintainers will let you know if a KEP is required.
- type: checkboxes
attributes:
label: Eschewed features
description: Some features are out of scope for Kustomize because they are incompatible with its foundational design principles. Please review the [Eschewed Features](https://kubectl.docs.kubernetes.io/faq/kustomize/eschewedfeatures/) documentation before submitting your feature request.
options:
- label: This issue is not requesting templating, unstuctured edits, build-time side-effects from args or env vars, or any other eschewed feature.
required: true
- type: textarea
id: feature-description
attributes:
label: What would you like to have added?
validations:
required: true
- type: textarea
id: rationale
attributes:
label: Why is this needed?
validations:
required: true
- type: textarea
id: current-alternatives
attributes:
label: Can you accomplish the motivating task without this feature, and if so, how?
validations:
required: true
- type: textarea
id: design-alternatives
attributes:
label: What other solutions have you considered?
validations:
required: true
- type: textarea
id: additional-info
attributes:
label: Anything else we should know?
validations:
required: false
- type: checkboxes
attributes:
label: Feature ownership
description: The Kustomize project, like many areas of Kubernetes, currently lacks enough contributors to adequately respond to all proposals that have merit. Offering to build and support the feature yourself can help get traction for your request.
options:
- label: I am interested in contributing this feature myself! 🎉
required: false

View File

@@ -1,9 +0,0 @@
---
name: Question
about: Ask a question about the kustomize
title: "[Question]"
labels: ""
assignees: ""
---
<!-- Please describe your question here -->

36
.github/workflows/apidiff.yml vendored Normal file
View 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 }}

View File

@@ -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.16
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.16
id: go
- name: Check out code into the Go module directory
uses: actions/checkout@v2
- 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.16
id: go
- name: Check out code into the Go module directory
uses: actions/checkout@v2
- 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.16
id: go
- name: Check out code into the Go module directory
uses: actions/checkout@v2
- 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
View 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 }}

View File

@@ -3,91 +3,37 @@
run:
deadline: 5m
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
- deadcode
- depguard
- dogsled
- dupl
- durationcheck
- errcheck
- errname
- errorlint
- exhaustive
# - exhaustivestruct
- exportloopref
# - forbidigo
- forcetypeassert
# - funlen
# - gci
- gochecknoglobals
- gochecknoinits
# - gocognit
- goconst
- gocritic
- gocyclo
# - godot
# - godox
enable-all: true
disable:
- cyclop
- exhaustivestruct
- forbidigo
- funlen
- gci
- gocognit
- godot
- godox
- goerr113
- gofmt
# - gofumpt
- goheader
- goimports
- gomnd
- gomoddirectives
- gomodguard
- goprintffuncname
- gosec
- gosimple
- govet
# - ifshort # too many false positives
- importas
- ineffassign
# - ireturn
- lll
- makezero
- misspell
- nakedret
- nestif
- nilerr
# - nilnil
# - nlreturn
# - noctx
- nolintlint
# - paralleltest
- prealloc
- predeclared
- promlinter
- revive
- rowserrcheck
- sqlclosecheck
- staticcheck
- structcheck
# - stylecheck
- tagliatelle
- tenv
- testpackage
- thelper
- tparallel
- typecheck
- unconvert
- unparam
- unused
- varcheck
# - varnamelen
- wastedassign
- whitespace
- wrapcheck
# - wsl
- gofumpt
- ifshort # too many false positives
- ireturn
- nilnil
- nlreturn
- noctx
- paralleltest
- stylecheck
- varnamelen
- wsl
- exhaustruct
- deadcode
- scopelint
- nonamedreturns
- golint
- maintidx
- nosnakecase
linters-settings:
dupl:
@@ -102,14 +48,15 @@ linters-settings:
arguments:
- [ "ID", "API", "JSON" ] # AllowList
- [ ] # DenyList
gomnd:
ignored-functions:
- os.WriteFile
- make
gomoddirectives:
replace-local: true
gosec:
config:
G306: "0644"
gomnd:
ignored-functions:
- ioutil.WriteFile
wrapcheck:
ignoreSigs:
# defaults

View File

@@ -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

View File

@@ -3,7 +3,7 @@
#
# Makefile for kustomize CLI and API.
LATEST_V4_RELEASE=v4.5.4
LATEST_RELEASE=v5.1.1
SHELL := /usr/bin/env bash
GOOS = $(shell go env GOOS)
@@ -75,7 +75,8 @@ $(MYGOBIN)/pluginator:
# Build from local source.
$(MYGOBIN)/kustomize: build-kustomize-api
cd kustomize; \
go install .
go install -ldflags "-X sigs.k8s.io/kustomize/api/provenance.buildDate=$(shell date -u +'%Y-%m-%dT%H:%M:%SZ')" \
.
kustomize: $(MYGOBIN)/kustomize
@@ -100,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
@@ -125,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 \
@@ -133,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:
@@ -152,7 +164,7 @@ functions-examples-all:
done
test-go-mod:
./hack/for-each-module.sh "go list -m -json all > /dev/null && go mod tidy -v"
./hack/for-each-module.sh "go mod tidy -v"
.PHONY:
verify-kustomize-e2e: $(MYGOBIN)/mdrip $(MYGOBIN)/kind
@@ -169,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

View File

@@ -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|') \

View File

@@ -34,7 +34,7 @@ _builtinplugins = \
HashTransformer.go \
ImageTagTransformer.go \
LabelTransformer.go \
LegacyOrderTransformer.go \
SortOrderTransformer.go \
NamespaceTransformer.go \
PatchJson6902Transformer.go \
PatchStrategicMergeTransformer.go \
@@ -63,7 +63,7 @@ $(pGen)/GkeSaGenerator.go: $(pSrc)/gkesagenerator/GkeSaGenerator.go
$(pGen)/HashTransformer.go: $(pSrc)/hashtransformer/HashTransformer.go
$(pGen)/ImageTagTransformer.go: $(pSrc)/imagetagtransformer/ImageTagTransformer.go
$(pGen)/LabelTransformer.go: $(pSrc)/labeltransformer/LabelTransformer.go
$(pGen)/LegacyOrderTransformer.go: $(pSrc)/legacyordertransformer/LegacyOrderTransformer.go
$(pGen)/SortOrderTransformer.go: $(pSrc)/sortordertransformer/SortOrderTransformer.go
$(pGen)/NamespaceTransformer.go: $(pSrc)/namespacetransformer/NamespaceTransformer.go
$(pGen)/PatchJson6902Transformer.go: $(pSrc)/patchjson6902transformer/PatchJson6902Transformer.go
$(pGen)/PatchStrategicMergeTransformer.go: $(pSrc)/patchstrategicmergetransformer/PatchStrategicMergeTransformer.go
@@ -79,7 +79,7 @@ $(pGen)/HelmChartInflationGenerator.go: $(pSrc)/helmchartinflationgenerator/Helm
# The (verbose but portable) Makefile way to convert to lowercase.
toLowerCase = $(subst A,a,$(subst B,b,$(subst C,c,$(subst D,d,$(subst E,e,$(subst F,f,$(subst G,g,$(subst H,h,$(subst I,i,$(subst J,j,$(subst K,k,$(subst L,l,$(subst M,m,$(subst N,n,$(subst O,o,$(subst P,p,$(subst Q,q,$(subst R,r,$(subst S,s,$(subst T,t,$(subst U,u,$(subst V,v,$(subst W,w,$(subst X,x,$(subst Y,y,$(subst Z,z,$1))))))))))))))))))))))))))
$(pGen)/%.go: $(MYGOBIN)/pluginator
$(pGen)/%.go: $(MYGOBIN)/pluginator $(MYGOBIN)/goimports
@echo "generating $*"
( \
set -e; \
@@ -89,9 +89,27 @@ $(pGen)/%.go: $(MYGOBIN)/pluginator
$(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:

View File

@@ -1,12 +1,17 @@
# Copyright 2022 The Kubernetes Authors.
# SPDX-License-Identifier: Apache-2.0
GOLANGCI_LINT_VERSION=v1.51.2
MYGOBIN = $(shell go env GOBIN)
ifeq ($(MYGOBIN),)
MYGOBIN = $(shell go env GOPATH)/bin
endif
export PATH := $(MYGOBIN):$(PATH)
# determines whether to run tests that only behave locally; can be overridden by override variable
export IS_LOCAL = false
.PHONY: install-out-of-tree-tools
install-out-of-tree-tools: \
$(MYGOBIN)/goimports \
@@ -25,7 +30,7 @@ uninstall-out-of-tree-tools:
rm -f $(MYGOBIN)/stringer
$(MYGOBIN)/golangci-lint:
go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.45.2
go install github.com/golangci/golangci-lint/cmd/golangci-lint@$(GOLANGCI_LINT_VERSION)
$(MYGOBIN)/mdrip:
go install github.com/monopole/mdrip@v1.0.2
@@ -42,9 +47,6 @@ $(MYGOBIN)/mdtogo:
$(MYGOBIN)/addlicense:
go install github.com/google/addlicense@latest
$(MYGOBIN)/statik:
go install github.com/rakyll/statik@latest
$(MYGOBIN)/goreleaser:
go install github.com/goreleaser/goreleaser@v0.179.0 # https://github.com/kubernetes-sigs/kustomize/issues/4542
@@ -92,7 +94,7 @@ $(MYGOBIN)/helmV3:
( \
set -e; \
d=$(shell mktemp -d); cd $$d; \
tgzFile=helm-v3.6.3-$(GOOS)-$(GOARCH).tar.gz; \
tgzFile=helm-v3.10.2-$(GOOS)-$(GOARCH).tar.gz; \
wget https://get.helm.sh/$$tgzFile; \
tar -xvzf $$tgzFile; \
mv $(GOOS)-$(GOARCH)/helm $(MYGOBIN)/helmV3; \

1
OWNERS
View File

@@ -1,6 +1,5 @@
# See https://github.com/kubernetes/community/blob/master/community-membership.md
approvers:
- kustomize-approvers
reviewers:
- kustomize-reviewers

View File

@@ -7,23 +7,20 @@ aliases:
kustomize-approvers:
- knverey
- natasha41575
- annasong20
- koba1t
kustomize-reviewers:
- knverey
- natasha41575
- yuwenma
kyaml-approvers:
- mengqiy
- mortent
- phanimarupaka
kyaml-reviewers:
- mengqiy
- mortent
- phanimarupaka
emeritus-approvers:
- liujingfang1
- Shell32-Natsu
- justinsb
- monopole
- pwittrock
- annasong20
- koba1t
# emeritus:
# - liujingfang1
# - Shell32-Natsu
# - justinsb
# - monopole
# - pwittrock
# - mengqiy
# - mortent
# - phanimarupaka

View File

@@ -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

View File

@@ -4,11 +4,10 @@
include ../Makefile-modules.mk
test:
go test -v -timeout 45m -cover ./... -ldflags "-X sigs.k8s.io/kustomize/api/provenance.version=v444.333.222"
cd krusty/openapitests; OPENAPI_TEST=true go test -v -timeout 45m -p 1 -cover ./...
go test -v -timeout 45m -cover ./... -ldflags "-X sigs.k8s.io/kustomize/api/provenance.buildDate=2023-01-31T23:38:41Z -X sigs.k8s.io/kustomize/api/provenance.version=(test)"
build:
go build -ldflags "-X sigs.k8s.io/kustomize/api/provenance.version=v444.333.222" ./...
go build -ldflags "-X sigs.k8s.io/kustomize/api/provenance.buildDate=$(shell date -u +"%Y-%m-%dT%H:%M:%SZ")" ./...
generate: $(MYGOBIN)/k8scopy $(MYGOBIN)/stringer
go generate ./...

View File

@@ -16,7 +16,6 @@ type (
IAMPolicyGeneratorPlugin = internal.IAMPolicyGeneratorPlugin
ImageTagTransformerPlugin = internal.ImageTagTransformerPlugin
LabelTransformerPlugin = internal.LabelTransformerPlugin
LegacyOrderTransformerPlugin = internal.LegacyOrderTransformerPlugin
NamespaceTransformerPlugin = internal.NamespaceTransformerPlugin
PatchJson6902TransformerPlugin = internal.PatchJson6902TransformerPlugin
PatchStrategicMergeTransformerPlugin = internal.PatchStrategicMergeTransformerPlugin
@@ -37,7 +36,6 @@ var (
NewIAMPolicyGeneratorPlugin = internal.NewIAMPolicyGeneratorPlugin
NewImageTagTransformerPlugin = internal.NewImageTagTransformerPlugin
NewLabelTransformerPlugin = internal.NewLabelTransformerPlugin
NewLegacyOrderTransformerPlugin = internal.NewLegacyOrderTransformerPlugin
NewNamespaceTransformerPlugin = internal.NewNamespaceTransformerPlugin
NewPatchJson6902TransformerPlugin = internal.NewPatchJson6902TransformerPlugin
NewPatchStrategicMergeTransformerPlugin = internal.NewPatchStrategicMergeTransformerPlugin

View File

@@ -12,13 +12,13 @@ type SetFn func(*yaml.RNode) error
// SetScalar returns a SetFn to set a scalar value
func SetScalar(value string) SetFn {
return func(node *yaml.RNode) error {
return node.PipeE(yaml.FieldSetter{StringValue: value})
}
return SetEntry("", value, yaml.NodeTagEmpty)
}
// SetEntry returns a SetFn to set an entry in a map
func SetEntry(key, value, tag string) SetFn {
// SetEntry returns a SetFn to set a field or a map entry to a value.
// It can be used with an empty name to set both a value and a tag on a scalar node.
// When setting only a value on a scalar node, use SetScalar instead.
func SetEntry(name, value, tag string) SetFn {
n := &yaml.Node{
Kind: yaml.ScalarNode,
Value: value,
@@ -26,7 +26,7 @@ func SetEntry(key, value, tag string) SetFn {
}
return func(node *yaml.RNode) error {
return node.PipeE(yaml.FieldSetter{
Name: key,
Name: name,
Value: yaml.NewRNode(n),
})
}
@@ -34,36 +34,72 @@ func SetEntry(key, value, tag string) SetFn {
type TrackableSetter struct {
// SetValueCallback will be invoked each time a field is set
setValueCallback func(key, value, tag string, node *yaml.RNode)
setValueCallback func(name, value, tag string, node *yaml.RNode)
}
// WithMutationTracker registers a callback which will be invoked each time a field is mutated
func (s *TrackableSetter) WithMutationTracker(callback func(key, value, tag string, node *yaml.RNode)) {
func (s *TrackableSetter) WithMutationTracker(callback func(key, value, tag string, node *yaml.RNode)) *TrackableSetter {
s.setValueCallback = callback
return s
}
// SetScalar returns a SetFn to set a scalar value
// SetScalar returns a SetFn to set a scalar value.
// if a mutation tracker has been registered, the tracker will be invoked each
// time a scalar is set
func (s TrackableSetter) SetScalar(value string) SetFn {
origSetScalar := SetScalar(value)
return s.SetEntry("", value, yaml.NodeTagEmpty)
}
// SetScalarIfEmpty returns a SetFn to set a scalar value only if it isn't already set.
// If a mutation tracker has been registered, the tracker will be invoked each
// time a scalar is actually set.
func (s TrackableSetter) SetScalarIfEmpty(value string) SetFn {
return s.SetEntryIfEmpty("", value, yaml.NodeTagEmpty)
}
// SetEntry returns a SetFn to set a field or a map entry to a value.
// It can be used with an empty name to set both a value and a tag on a scalar node.
// When setting only a value on a scalar node, use SetScalar instead.
// If a mutation tracker has been registered, the tracker will be invoked each
// time an entry is set.
func (s TrackableSetter) SetEntry(name, value, tag string) SetFn {
origSetEntry := SetEntry(name, value, tag)
return func(node *yaml.RNode) error {
if s.setValueCallback != nil {
s.setValueCallback("", value, "", node)
s.setValueCallback(name, value, tag, node)
}
return origSetScalar(node)
return origSetEntry(node)
}
}
// SetEntry returns a SetFn to set an entry in a map
// if a mutation tracker has been registered, the tracker will be invoked each
// time an entry is set
func (s TrackableSetter) SetEntry(key, value, tag string) SetFn {
// SetEntryIfEmpty returns a SetFn to set a field or a map entry to a value only if it isn't already set.
// It can be used with an empty name to set both a value and a tag on a scalar node.
// When setting only a value on a scalar node, use SetScalar instead.
// If a mutation tracker has been registered, the tracker will be invoked each
// time an entry is actually set.
func (s TrackableSetter) SetEntryIfEmpty(key, value, tag string) SetFn {
origSetEntry := SetEntry(key, value, tag)
return func(node *yaml.RNode) error {
if hasExistingValue(node, key) {
return nil
}
if s.setValueCallback != nil {
s.setValueCallback(key, value, tag, node)
}
return origSetEntry(node)
}
}
func hasExistingValue(node *yaml.RNode, key string) bool {
if node.IsNilOrEmpty() {
return false
}
if err := yaml.ErrorIfInvalid(node, yaml.ScalarNode); err == nil {
return yaml.GetValue(node) != ""
}
entry := node.Field(key)
if entry.IsNilOrEmpty() {
return false
}
return yaml.GetValue(entry.Value) != ""
}

View File

@@ -0,0 +1,108 @@
// Copyright 2022 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package filtersutil_test
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"sigs.k8s.io/kustomize/api/filters/filtersutil"
"sigs.k8s.io/kustomize/kyaml/yaml"
)
func TestTrackableSetter_SetScalarIfEmpty(t *testing.T) {
tests := []struct {
name string
input *yaml.RNode
value string
want string
}{
{
name: "sets null values",
input: yaml.MakeNullNode(),
value: "foo",
want: "foo",
},
{
name: "sets empty values",
input: yaml.NewScalarRNode(""),
value: "foo",
want: "foo",
},
{
name: "does not overwrite values",
input: yaml.NewStringRNode("a"),
value: "foo",
want: "a",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
wasSet := false
s := (&filtersutil.TrackableSetter{}).WithMutationTracker(func(_, _, _ string, _ *yaml.RNode) {
wasSet = true
})
wantSet := tt.value == tt.want
fn := s.SetScalarIfEmpty(tt.value)
require.NoError(t, fn(tt.input))
assert.Equal(t, tt.want, yaml.GetValue(tt.input))
assert.Equal(t, wantSet, wasSet, "tracker invoked even though value was not changed")
})
}
}
func TestTrackableSetter_SetEntryIfEmpty(t *testing.T) {
tests := []struct {
name string
input *yaml.RNode
key string
value string
want string
}{
{
name: "sets empty values",
input: yaml.NewMapRNode(&map[string]string{"setMe": ""}),
key: "setMe",
value: "foo",
want: "foo",
},
{
name: "sets missing keys",
input: yaml.NewMapRNode(&map[string]string{}),
key: "setMe",
value: "foo",
want: "foo",
},
{
name: "does not overwrite values",
input: yaml.NewMapRNode(&map[string]string{"existing": "original"}),
key: "existing",
value: "foo",
want: "original",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
wasSet := false
s := (&filtersutil.TrackableSetter{}).WithMutationTracker(func(_, _, _ string, _ *yaml.RNode) {
wasSet = true
})
wantSet := tt.value == tt.want
fn := s.SetEntryIfEmpty(tt.key, tt.value, "")
require.NoError(t, fn(tt.input))
assert.Equal(t, tt.want, yaml.GetValue(tt.input.Field(tt.key).Value))
assert.Equal(t, wantSet, wasSet, "tracker invoked even though value was not changed")
})
}
}
func TestTrackableSetter_SetEntryIfEmpty_BadInputNodeKind(t *testing.T) {
fn := filtersutil.TrackableSetter{}.SetEntryIfEmpty("foo", "false", yaml.NodeTagBool)
rn := yaml.NewListRNode("nope")
rn.AppendToFieldPath("dummy", "path")
assert.EqualError(t, fn(rn), `wrong node kind: expected MappingNode but got SequenceNode: node contents:
- nope
`)
}

View File

@@ -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"
)

View File

@@ -7,11 +7,11 @@ import (
"fmt"
"strings"
"github.com/pkg/errors"
"sigs.k8s.io/kustomize/api/filters/fieldspec"
"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"
"sigs.k8s.io/kustomize/kyaml/resid"
"sigs.k8s.io/kustomize/kyaml/yaml"
@@ -64,7 +64,7 @@ func (f Filter) run(node *yaml.RNode) (*yaml.RNode, error) {
FieldSpec: f.NameFieldToUpdate,
SetValue: f.set,
}); err != nil {
return nil, errors.Wrapf(
return nil, errors.WrapPrefixf(
err, "updating name reference in '%s' field of '%s'",
f.NameFieldToUpdate.Path, f.Referrer.CurId().String())
}
@@ -104,7 +104,7 @@ func (f Filter) setMapping(node *yaml.RNode) error {
}
nameNode, err := node.Pipe(yaml.FieldMatcher{Name: "name"})
if err != nil {
return errors.Wrap(err, "trying to match 'name' field")
return errors.WrapPrefixf(err, "trying to match 'name' field")
}
if nameNode == nil {
// This is a _configuration_ error; the field path
@@ -118,7 +118,9 @@ func (f Filter) setMapping(node *yaml.RNode) error {
return err
}
oldName := nameNode.YNode().Value
referral, err := f.selectReferral(oldName, candidates)
// use allNamesAndNamespacesAreTheSame to compare referral candidates for functional identity,
// because we source both name and namespace values from the referral in this case.
referral, err := f.selectReferral(oldName, candidates, allNamesAndNamespacesAreTheSame)
if err != nil || referral == nil {
// Nil referral means nothing to do.
return err
@@ -151,7 +153,7 @@ func (f Filter) filterMapCandidatesByNamespace(
node *yaml.RNode) ([]*resource.Resource, error) {
namespaceNode, err := node.Pipe(yaml.FieldMatcher{Name: "namespace"})
if err != nil {
return nil, errors.Wrap(err, "trying to match 'namespace' field")
return nil, errors.WrapPrefixf(err, "trying to match 'namespace' field")
}
if namespaceNode == nil {
return f.ReferralCandidates.Resources(), nil
@@ -167,8 +169,10 @@ func (f Filter) filterMapCandidatesByNamespace(
}
func (f Filter) setScalar(node *yaml.RNode) error {
// use allNamesAreTheSame to compare referral candidates for functional identity,
// because we only source the name from the referral in this case.
referral, err := f.selectReferral(
node.YNode().Value, f.ReferralCandidates.Resources())
node.YNode().Value, f.ReferralCandidates.Resources(), allNamesAreTheSame)
if err != nil || referral == nil {
// Nil referral means nothing to do.
return err
@@ -311,7 +315,9 @@ func (f Filter) sameCurrentNamespaceAsReferrer() sieveFunc {
func (f Filter) selectReferral(
// The name referral that may need to be updated.
oldName string,
candidates []*resource.Resource) (*resource.Resource, error) {
candidates []*resource.Resource,
// function that returns whether two referrals are identical for the purposes of the transformation
candidatesIdentical func(resources []*resource.Resource) bool) (*resource.Resource, error) {
candidates = doSieve(candidates, previousNameMatches(oldName))
candidates = doSieve(candidates, previousIdSelectedByGvk(&f.ReferralTarget))
candidates = doSieve(candidates, f.roleRefFilter())
@@ -326,24 +332,21 @@ func (f Filter) selectReferral(
if len(candidates) == 0 {
return nil, nil
}
if allNamesAreTheSame(candidates) {
if candidatesIdentical(candidates) {
// Just take the first one.
return candidates[0], nil
}
ids := getIds(candidates)
f.failureDetails(candidates)
return nil, fmt.Errorf(" found multiple possible referrals: %s", ids)
return nil, fmt.Errorf("found multiple possible referrals: %s\n%s", ids, f.failureDetails(candidates))
}
func (f Filter) failureDetails(resources []*resource.Resource) {
fmt.Printf(
"\n**** Too many possible referral targets to referrer:\n%s\n",
f.Referrer.MustYaml())
func (f Filter) failureDetails(resources []*resource.Resource) string {
msg := strings.Builder{}
msg.WriteString(fmt.Sprintf("\n**** Too many possible referral targets to referrer:\n%s\n", f.Referrer.MustYaml()))
for i, r := range resources {
fmt.Printf(
"--- possible referral %d:\n%s", i, r.MustYaml())
fmt.Println("------")
msg.WriteString(fmt.Sprintf("--- possible referral %d:\n%s\n", i, r.MustYaml()))
}
return msg.String()
}
func allNamesAreTheSame(resources []*resource.Resource) bool {
@@ -356,6 +359,17 @@ func allNamesAreTheSame(resources []*resource.Resource) bool {
return true
}
func allNamesAndNamespacesAreTheSame(resources []*resource.Resource) bool {
name := resources[0].GetName()
namespace := resources[0].GetNamespace()
for i := 1; i < len(resources); i++ {
if name != resources[i].GetName() || namespace != resources[i].GetNamespace() {
return false
}
}
return true
}
func getIds(rs []*resource.Resource) string {
var result []string
for _, r := range rs {

View File

@@ -7,6 +7,7 @@ import (
"sigs.k8s.io/kustomize/api/filters/filtersutil"
"sigs.k8s.io/kustomize/api/filters/fsslice"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/errors"
"sigs.k8s.io/kustomize/kyaml/kio"
"sigs.k8s.io/kustomize/kyaml/resid"
"sigs.k8s.io/kustomize/kyaml/yaml"
@@ -19,9 +20,28 @@ type Filter struct {
// FsSlice contains the FieldSpecs to locate the namespace field
FsSlice types.FsSlice `json:"fieldSpecs,omitempty" yaml:"fieldSpecs,omitempty"`
// UnsetOnly means only blank namespace fields will be set
UnsetOnly bool `json:"unsetOnly" yaml:"unsetOnly"`
// SetRoleBindingSubjects determines which subject fields in RoleBinding and ClusterRoleBinding
// objects will have their namespace fields set. Overrides field specs provided for these types, if any.
// - defaultOnly (default): namespace will be set only on subjects named "default".
// - allServiceAccounts: namespace will be set on all subjects with "kind: ServiceAccount"
// - none: all subjects will be skipped.
SetRoleBindingSubjects RoleBindingSubjectMode `json:"setRoleBindingSubjects" yaml:"setRoleBindingSubjects"`
trackableSetter filtersutil.TrackableSetter
}
type RoleBindingSubjectMode string
const (
DefaultSubjectsOnly RoleBindingSubjectMode = "defaultOnly"
SubjectModeUnspecified RoleBindingSubjectMode = ""
AllServiceAccountSubjects RoleBindingSubjectMode = "allServiceAccounts"
NoSubjects RoleBindingSubjectMode = "none"
)
var _ kio.Filter = Filter{}
var _ kio.TrackableFilter = &Filter{}
@@ -36,47 +56,40 @@ 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) {
// hacks for hardcoded types -- :(
if err := ns.hacks(node); err != nil {
// Special handling for metadata.namespace and metadata.name -- :(
// never let SetEntry handle metadata.namespace--it will incorrectly include cluster-scoped resources
// 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
}
// Remove the fieldspecs that are for hardcoded fields. The fieldspecs
// exist for backwards compatibility with other implementations
// of this transformation.
// This implementation of the namespace transformation
// Does not use the fieldspecs for implementing cases which
// require hardcoded logic.
ns.FsSlice = ns.removeFieldSpecsForHacks(ns.FsSlice)
// Special handling for (cluster) role binding subjects -- :(
if isRoleBinding(gvk.Kind) {
ns.FsSlice = ns.removeRoleBindingSubjectFieldSpecs(ns.FsSlice)
if err := ns.roleBindingHack(node); err != nil {
return nil, err
}
}
// transformations based on data -- :)
err := node.PipeE(fsslice.Filter{
FsSlice: ns.FsSlice,
SetValue: ns.trackableSetter.SetEntry("", ns.Namespace, yaml.NodeTagString),
SetValue: ns.fieldSetter(),
CreateKind: yaml.ScalarNode, // Namespace is a ScalarNode
CreateTag: yaml.NodeTagString,
})
return node, err
}
// hacks applies the namespace transforms that are hardcoded rather
// than specified through FieldSpecs.
func (ns Filter) hacks(obj *yaml.RNode) error {
gvk := resid.GvkFromNode(obj)
if err := ns.metaNamespaceHack(obj, gvk); err != nil {
return err
invalidKindErr := &yaml.InvalidNodeKindError{}
if err != nil && errors.As(err, &invalidKindErr) && invalidKindErr.ActualNodeKind() != yaml.ScalarNode {
return nil, errors.WrapPrefixf(err, "namespace field specs must target scalar nodes")
}
return ns.roleBindingHack(obj, gvk)
return node, errors.WrapPrefixf(err, "namespace transformation failed")
}
// metaNamespaceHack is a hack for implementing the namespace transform
// for the metadata.namespace field on namespace scoped resources.
// namespace scoped resources are determined by NOT being present
// in a hard-coded list of cluster-scoped resource types (by apiVersion and kind).
//
// This hack should be updated to allow individual resources to specify
// if they are cluster scoped through either an annotation on the resources,
// or through inlined OpenAPI on the resource as a YAML comment.
func (ns Filter) metaNamespaceHack(obj *yaml.RNode, gvk resid.Gvk) error {
if gvk.IsClusterScoped() {
return nil
@@ -85,19 +98,23 @@ func (ns Filter) metaNamespaceHack(obj *yaml.RNode, gvk resid.Gvk) error {
FsSlice: []types.FieldSpec{
{Path: types.MetadataNamespacePath, CreateIfNotPresent: true},
},
SetValue: ns.trackableSetter.SetEntry("", ns.Namespace, yaml.NodeTagString),
SetValue: ns.fieldSetter(),
CreateKind: yaml.ScalarNode, // Namespace is a ScalarNode
}
_, err := f.Filter(obj)
return err
}
// roleBindingHack is a hack for implementing the namespace transform
// roleBindingHack is a hack for implementing the transformer's SetRoleBindingSubjects option
// for RoleBinding and ClusterRoleBinding resource types.
// RoleBinding and ClusterRoleBinding have namespace set on
//
// In NoSubjects mode, it does nothing.
//
// In AllServiceAccountSubjects mode, it sets the namespace on subjects with "kind: ServiceAccount".
//
// In DefaultSubjectsOnly mode (default mode), RoleBinding and ClusterRoleBinding have namespace set on
// elements of the "subjects" field if and only if the subject elements
// "name" is "default". Otherwise the namespace is not set.
//
// Example:
//
// kind: RoleBinding
@@ -106,59 +123,64 @@ func (ns Filter) metaNamespaceHack(obj *yaml.RNode, gvk resid.Gvk) error {
// ...
// - name: "something-else" # this will not have the namespace set
// ...
func (ns Filter) roleBindingHack(obj *yaml.RNode, gvk resid.Gvk) error {
if gvk.Kind != roleBindingKind && gvk.Kind != clusterRoleBindingKind {
func (ns Filter) roleBindingHack(obj *yaml.RNode) error {
var visitor filtersutil.SetFn
switch ns.SetRoleBindingSubjects {
case NoSubjects:
return nil
case DefaultSubjectsOnly, SubjectModeUnspecified:
visitor = ns.setSubjectsNamedDefault
case AllServiceAccountSubjects:
visitor = ns.setServiceAccountNamespaces
default:
return errors.Errorf("invalid value %q for setRoleBindingSubjects: "+
"must be one of %q, %q or %q", ns.SetRoleBindingSubjects,
DefaultSubjectsOnly, NoSubjects, AllServiceAccountSubjects)
}
// Lookup the namespace field on all elements.
// We should change the fieldspec so this isn't necessary.
// Lookup the subjects field on all elements.
obj, err := obj.Pipe(yaml.Lookup(subjectsField))
if err != nil || yaml.IsMissingOrNull(obj) {
return err
}
// add the namespace to each "subject" with name: default
err = obj.VisitElements(func(o *yaml.RNode) error {
// The only case we need to force the namespace
// if for the "service account". "default" is
// kind of hardcoded here for right now.
name, err := o.Pipe(
yaml.Lookup("name"), yaml.Match("default"),
)
if err != nil || yaml.IsMissingOrNull(name) {
return err
}
// set the namespace for the default account
node, err := o.Pipe(
yaml.LookupCreate(yaml.ScalarNode, "namespace"),
)
if err != nil {
return err
}
return ns.trackableSetter.SetEntry("", ns.Namespace, yaml.NodeTagString)(node)
})
return err
// Use the appropriate visitor to set the namespace field on the correct subset of subjects
return errors.WrapPrefixf(obj.VisitElements(visitor), "setting namespace on (cluster)role binding subjects")
}
// removeFieldSpecsForHacks removes from the list fieldspecs that
func isRoleBinding(kind string) bool {
return kind == roleBindingKind || kind == clusterRoleBindingKind
}
func (ns Filter) setServiceAccountNamespaces(o *yaml.RNode) error {
name, err := o.Pipe(yaml.Lookup("kind"), yaml.Match("ServiceAccount"))
if err != nil || yaml.IsMissingOrNull(name) {
return errors.WrapPrefixf(err, "looking up kind on (cluster)role binding subject")
}
return setNamespaceField(o, ns.fieldSetter())
}
func (ns Filter) setSubjectsNamedDefault(o *yaml.RNode) error {
name, err := o.Pipe(yaml.Lookup("name"), yaml.Match("default"))
if err != nil || yaml.IsMissingOrNull(name) {
return errors.WrapPrefixf(err, "looking up name on (cluster)role binding subject")
}
return setNamespaceField(o, ns.fieldSetter())
}
func setNamespaceField(node *yaml.RNode, setter filtersutil.SetFn) error {
node, err := node.Pipe(yaml.LookupCreate(yaml.ScalarNode, "namespace"))
if err != nil {
return errors.WrapPrefixf(err, "setting namespace field on (cluster)role binding subject")
}
return setter(node)
}
// removeRoleBindingSubjectFieldSpecs removes from the list fieldspecs that
// have hardcoded implementations
func (ns Filter) removeFieldSpecsForHacks(fs types.FsSlice) types.FsSlice {
func (ns Filter) removeRoleBindingSubjectFieldSpecs(fs types.FsSlice) types.FsSlice {
var val types.FsSlice
for i := range fs {
// implemented by metaNamespaceHack
if fs[i].Path == types.MetadataNamespacePath {
continue
}
// implemented by roleBindingHack
if fs[i].Kind == roleBindingKind && fs[i].Path == subjectsField {
continue
}
// implemented by roleBindingHack
if fs[i].Kind == clusterRoleBindingKind && fs[i].Path == subjectsField {
if isRoleBinding(fs[i].Kind) && fs[i].Path == subjectsNamespacePath {
continue
}
val = append(val, fs[i])
@@ -166,8 +188,30 @@ func (ns Filter) removeFieldSpecsForHacks(fs types.FsSlice) types.FsSlice {
return val
}
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
}
func (ns *Filter) fieldSetter() filtersutil.SetFn {
if ns.UnsetOnly {
return ns.trackableSetter.SetEntryIfEmpty("", ns.Namespace, yaml.NodeTagString)
}
return ns.trackableSetter.SetEntry("", ns.Namespace, yaml.NodeTagString)
}
const (
subjectsField = "subjects"
subjectsNamespacePath = "subjects/namespace"
roleBindingKind = "RoleBinding"
clusterRoleBindingKind = "ClusterRoleBinding"
)

View File

@@ -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"

View File

@@ -732,6 +732,177 @@ spec:
protocol: "TCP"
- containerPort: 8301
protocol: "UDP"
`,
},
// Issue #4628
"should retain existing null values in targets": {
input: `
apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
metadata:
name: chart
spec:
releaseName: helm-chart
timeout: 15m
values:
chart:
replicaCount: null
autoscaling: true
`,
patch: yaml.MustParse(`
apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
metadata:
name: chart
spec:
releaseName: helm-chart
timeout: 15m
values:
deepgram-api:
some: value
`),
expected: `
apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
metadata:
name: chart
spec:
releaseName: helm-chart
timeout: 15m
values:
chart:
replicaCount: null
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"
`,
},
}

View File

@@ -4,13 +4,13 @@
package replacement
import (
"errors"
"fmt"
"strings"
"sigs.k8s.io/kustomize/api/internal/utils"
"sigs.k8s.io/kustomize/api/resource"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/errors"
"sigs.k8s.io/kustomize/kyaml/resid"
kyaml_utils "sigs.k8s.io/kustomize/kyaml/utils"
"sigs.k8s.io/kustomize/kyaml/yaml"
@@ -38,22 +38,86 @@ func (f Filter) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) {
return nodes, nil
}
func applyReplacement(nodes []*yaml.RNode, value *yaml.RNode, targets []*types.TargetSelector) ([]*yaml.RNode, error) {
for _, t := range targets {
if t.Select == nil {
return nil, fmt.Errorf("target must specify resources to select")
func getReplacement(nodes []*yaml.RNode, r *types.Replacement) (*yaml.RNode, error) {
source, err := selectSourceNode(nodes, r.Source)
if err != nil {
return nil, err
}
if r.Source.FieldPath == "" {
r.Source.FieldPath = types.DefaultReplacementFieldPath
}
fieldPath := kyaml_utils.SmarterPathSplitter(r.Source.FieldPath, ".")
rn, err := source.Pipe(yaml.Lookup(fieldPath...))
if err != nil {
return nil, fmt.Errorf("error looking up replacement source: %w", err)
}
if rn.IsNilOrEmpty() {
return nil, fmt.Errorf("fieldPath `%s` is missing for replacement source %s", r.Source.FieldPath, r.Source.ResId)
}
return getRefinedValue(r.Source.Options, rn)
}
// selectSourceNode finds the node that matches the selector, returning
// an error if multiple or none are found
func selectSourceNode(nodes []*yaml.RNode, selector *types.SourceSelector) (*yaml.RNode, error) {
var matches []*yaml.RNode
for _, n := range nodes {
ids, err := utils.MakeResIds(n)
if err != nil {
return nil, fmt.Errorf("error getting node IDs: %w", err)
}
if len(t.FieldPaths) == 0 {
t.FieldPaths = []string{types.DefaultReplacementFieldPath}
for _, id := range ids {
if id.IsSelectedBy(selector.ResId) {
if len(matches) > 0 {
return nil, fmt.Errorf(
"multiple matches for selector %s", selector)
}
matches = append(matches, n)
break
}
}
for _, n := range nodes {
ids, err := utils.MakeResIds(n)
}
if len(matches) == 0 {
return nil, fmt.Errorf("nothing selected by %s", selector)
}
return matches[0], nil
}
func getRefinedValue(options *types.FieldOptions, rn *yaml.RNode) (*yaml.RNode, error) {
if options == nil || options.Delimiter == "" {
return rn, nil
}
if rn.YNode().Kind != yaml.ScalarNode {
return nil, fmt.Errorf("delimiter option can only be used with scalar nodes")
}
value := strings.Split(yaml.GetValue(rn), options.Delimiter)
if options.Index >= len(value) || options.Index < 0 {
return nil, fmt.Errorf("options.index %d is out of bounds for value %s", options.Index, yaml.GetValue(rn))
}
n := rn.Copy()
n.YNode().Value = value[options.Index]
return n, nil
}
func applyReplacement(nodes []*yaml.RNode, value *yaml.RNode, targetSelectors []*types.TargetSelector) ([]*yaml.RNode, error) {
for _, selector := range targetSelectors {
if selector.Select == nil {
return nil, errors.Errorf("target must specify resources to select")
}
if len(selector.FieldPaths) == 0 {
selector.FieldPaths = []string{types.DefaultReplacementFieldPath}
}
for _, possibleTarget := range nodes {
ids, err := utils.MakeResIds(possibleTarget)
if err != nil {
return nil, err
}
// filter targets by label and annotation selectors
selectByAnnoAndLabel, err := selectByAnnoAndLabel(n, t)
selectByAnnoAndLabel, err := selectByAnnoAndLabel(possibleTarget, selector)
if err != nil {
return nil, err
}
@@ -62,9 +126,9 @@ func applyReplacement(nodes []*yaml.RNode, value *yaml.RNode, targets []*types.T
}
// filter targets by matching resource IDs
for i, id := range ids {
if id.IsSelectedBy(t.Select.ResId) && !rejectId(t.Reject, &ids[i]) {
err := applyToNode(n, value, t)
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
}
@@ -104,38 +168,42 @@ 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
}
func applyToNode(node *yaml.RNode, value *yaml.RNode, target *types.TargetSelector) error {
for _, fp := range target.FieldPaths {
fieldPath := kyaml_utils.SmarterPathSplitter(fp, ".")
var t *yaml.RNode
var err error
if target.Options != nil && target.Options.Create {
// create option is not supported in a wildcard matching.
// Because, PathMatcher is not supported create option.
// So, if create option is set, we fallback to PathGetter.
for _, f := range fieldPath {
if f == "*" {
return errors.New("cannot support create option in a multi-value target") //nolint:goerr113
}
}
t, err = node.Pipe(yaml.LookupCreate(value.YNode().Kind, fieldPath...))
} else {
t, err = node.Pipe(&yaml.PathMatcher{Path: fieldPath})
func copyValueToTarget(target *yaml.RNode, value *yaml.RNode, selector *types.TargetSelector) error {
for _, fp := range selector.FieldPaths {
createKind := yaml.Kind(0) // do not create
if selector.Options != nil && selector.Options.Create {
createKind = value.YNode().Kind
}
targetFieldList, err := target.Pipe(&yaml.PathMatcher{
Path: kyaml_utils.SmarterPathSplitter(fp, "."),
Create: createKind})
if err != nil {
return err
return errors.WrapPrefixf(err, fieldRetrievalError(fp, createKind != 0))
}
if t != nil {
if err = applyToOneNode(target.Options, t, value); err != nil {
targetFields, err := targetFieldList.Elements()
if err != nil {
return errors.WrapPrefixf(err, fieldRetrievalError(fp, createKind != 0))
}
if len(targetFields) == 0 {
return errors.Errorf(fieldRetrievalError(fp, createKind != 0))
}
for _, t := range targetFields {
if err := setFieldValue(selector.Options, t, value); err != nil {
return err
}
}
@@ -143,31 +211,20 @@ func applyToNode(node *yaml.RNode, value *yaml.RNode, target *types.TargetSelect
return nil
}
func applyToOneNode(options *types.FieldOptions, t *yaml.RNode, value *yaml.RNode) error {
if len(t.YNode().Content) == 0 {
if err := setTargetValue(options, t, value); err != nil {
return err
}
return nil
func fieldRetrievalError(fieldPath string, isCreate bool) string {
if isCreate {
return fmt.Sprintf("unable to find or create field %q in replacement target", fieldPath)
}
for _, scalarNode := range t.YNode().Content {
rn := yaml.NewRNode(scalarNode)
if err := setTargetValue(options, rn, value); err != nil {
return err
}
}
return nil
return fmt.Sprintf("unable to find field %q in replacement target", fieldPath)
}
func setTargetValue(options *types.FieldOptions, t *yaml.RNode, value *yaml.RNode) error {
func setFieldValue(options *types.FieldOptions, targetField *yaml.RNode, value *yaml.RNode) error {
value = value.Copy()
if options != nil && options.Delimiter != "" {
if t.YNode().Kind != yaml.ScalarNode {
if targetField.YNode().Kind != yaml.ScalarNode {
return fmt.Errorf("delimiter option can only be used with scalar nodes")
}
tv := strings.Split(t.YNode().Value, options.Delimiter)
tv := strings.Split(targetField.YNode().Value, options.Delimiter)
v := yaml.GetValue(value)
// TODO: Add a way to remove an element
switch {
@@ -181,76 +238,12 @@ func setTargetValue(options *types.FieldOptions, t *yaml.RNode, value *yaml.RNod
value.YNode().Value = strings.Join(tv, options.Delimiter)
}
if t.YNode().Kind == yaml.ScalarNode {
if targetField.YNode().Kind == yaml.ScalarNode {
// For scalar, only copy the value (leave any type intact to auto-convert int->string or string->int)
t.YNode().Value = value.YNode().Value
targetField.YNode().Value = value.YNode().Value
} else {
t.SetYNode(value.YNode())
targetField.SetYNode(value.YNode())
}
return nil
}
func getReplacement(nodes []*yaml.RNode, r *types.Replacement) (*yaml.RNode, error) {
source, err := selectSourceNode(nodes, r.Source)
if err != nil {
return nil, err
}
if r.Source.FieldPath == "" {
r.Source.FieldPath = types.DefaultReplacementFieldPath
}
fieldPath := kyaml_utils.SmarterPathSplitter(r.Source.FieldPath, ".")
rn, err := source.Pipe(yaml.Lookup(fieldPath...))
if err != nil {
return nil, err
}
if rn.IsNilOrEmpty() {
return nil, fmt.Errorf("fieldPath `%s` is missing for replacement source %s", r.Source.FieldPath, r.Source.ResId)
}
return getRefinedValue(r.Source.Options, rn)
}
func getRefinedValue(options *types.FieldOptions, rn *yaml.RNode) (*yaml.RNode, error) {
if options == nil || options.Delimiter == "" {
return rn, nil
}
if rn.YNode().Kind != yaml.ScalarNode {
return nil, fmt.Errorf("delimiter option can only be used with scalar nodes")
}
value := strings.Split(yaml.GetValue(rn), options.Delimiter)
if options.Index >= len(value) || options.Index < 0 {
return nil, fmt.Errorf("options.index %d is out of bounds for value %s", options.Index, yaml.GetValue(rn))
}
n := rn.Copy()
n.YNode().Value = value[options.Index]
return n, nil
}
// selectSourceNode finds the node that matches the selector, returning
// an error if multiple or none are found
func selectSourceNode(nodes []*yaml.RNode, selector *types.SourceSelector) (*yaml.RNode, error) {
var matches []*yaml.RNode
for _, n := range nodes {
ids, err := utils.MakeResIds(n)
if err != nil {
return nil, err
}
for _, id := range ids {
if id.IsSelectedBy(selector.ResId) {
if len(matches) > 0 {
return nil, fmt.Errorf(
"multiple matches for selector %s", selector)
}
matches = append(matches, n)
break
}
}
}
if len(matches) == 0 {
return nil, fmt.Errorf("nothing selected by %s", selector)
}
return matches[0], nil
}

View File

@@ -9,7 +9,7 @@ import (
"github.com/stretchr/testify/assert"
filtertest "sigs.k8s.io/kustomize/api/testutils/filtertest"
"sigs.k8s.io/yaml"
"sigs.k8s.io/kustomize/kyaml/yaml"
)
func TestFilter(t *testing.T) {
@@ -1198,11 +1198,6 @@ apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy1
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy2
`,
replacements: `replacements:
- source:
@@ -1216,15 +1211,6 @@ metadata:
- spec.template.spec.containers
options:
create: true
- source:
kind: Pod
name: pod
fieldPath: spec.containers
targets:
- select:
name: deploy2
fieldPaths:
- spec.template.spec.containers
`,
expected: `apiVersion: v1
kind: Pod
@@ -1245,11 +1231,6 @@ spec:
containers:
- image: busybox
name: myapp-container
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: deploy2
`,
},
"complex type with delimiter in source": {
@@ -1498,6 +1479,85 @@ spec:
value: sample-deploy
- name: foo
value: bar
- image: nginx
name: sidecar
env:
- name: deployment-name
value: sample-deploy`,
},
"one replacements target should create multiple values": {
input: `apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: sample-deploy
name: sample-deploy
spec:
replicas: 1
selector:
matchLabels:
app: sample-deploy
template:
metadata:
labels:
app: sample-deploy
spec:
containers:
- image: other
name: do-not-modify-me
env:
- name: foo
value: bar
- image: nginx
name: main
env:
- name: foo
value: bar
- image: nginx
name: sidecar
`,
replacements: `replacements:
- source:
kind: Deployment
name: sample-deploy
fieldPath: metadata.name
targets:
- select:
kind: Deployment
options:
create: true
fieldPaths:
- spec.template.spec.containers.[image=nginx].env.[name=deployment-name].value
`,
expected: `apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: sample-deploy
name: sample-deploy
spec:
replicas: 1
selector:
matchLabels:
app: sample-deploy
template:
metadata:
labels:
app: sample-deploy
spec:
containers:
- image: other
name: do-not-modify-me
env:
- name: foo
value: bar
- image: nginx
name: main
env:
- name: foo
value: bar
- name: deployment-name
value: sample-deploy
- image: nginx
name: sidecar
env:
@@ -1671,7 +1731,110 @@ spec:
options:
create: true
`,
expectedErr: "cannot support create option in a multi-value target",
expected: `apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: sample-deploy
name: sample-deploy
spec:
replicas: 1
selector:
matchLabels:
app: sample-deploy
template:
metadata:
labels:
app: sample-deploy
spec:
containers:
- image: nginx
name: main
env:
- name: other-env
value: YYYYY
- name: deployment-name
value: sample-deploy
`,
},
"Issue 1493: wildcard to create or replace field in all containers in all workloads": {
input: `apiVersion: v1
kind: ConfigMap
metadata:
name: policy
data:
restart: OnFailure
---
apiVersion: v1
kind: Pod
metadata:
name: pod1
spec:
containers:
- image: nginx
name: main
- image: nginx
name: sidecar
imagePullPolicy: Always
---
apiVersion: v1
kind: Pod
metadata:
name: pod2
spec:
containers:
- image: nginx
name: main
imagePullPolicy: Always
- image: nginx
name: sidecar
`,
replacements: `replacements:
- source:
kind: ConfigMap
name: policy
fieldPath: data.restart
targets:
- select:
kind: Pod
fieldPaths:
- spec.containers.*.imagePullPolicy
options:
create: true
`,
expected: `apiVersion: v1
kind: ConfigMap
metadata:
name: policy
data:
restart: OnFailure
---
apiVersion: v1
kind: Pod
metadata:
name: pod1
spec:
containers:
- image: nginx
name: main
imagePullPolicy: OnFailure
- image: nginx
name: sidecar
imagePullPolicy: OnFailure
---
apiVersion: v1
kind: Pod
metadata:
name: pod2
spec:
containers:
- image: nginx
name: main
imagePullPolicy: OnFailure
- image: nginx
name: sidecar
imagePullPolicy: OnFailure
`,
},
"multiple field paths in target": {
input: `apiVersion: v1
@@ -2356,6 +2519,317 @@ spec:
- containerPort: 80
`,
},
"replace an existing mapping value": {
input: `apiVersion: batch/v1
kind: Job
metadata:
name: hello
spec:
template:
spec:
containers:
- image: busybox
name: myapp-container
restartPolicy: old
---
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- image: busybox
name: myapp-container
restartPolicy: new
`,
replacements: `replacements:
- source:
kind: Pod
name: my-pod
fieldPath: spec
targets:
- select:
name: hello
kind: Job
fieldPaths:
- spec.template.spec
options:
create: true
`,
expected: `apiVersion: batch/v1
kind: Job
metadata:
name: hello
spec:
template:
spec:
containers:
- image: busybox
name: myapp-container
restartPolicy: new
---
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- image: busybox
name: myapp-container
restartPolicy: new
`,
},
"issue4761 - path not in target with create: true": {
input: `
---
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: request-id
spec:
configPatches:
- applyTo: NETWORK_FILTER
- applyTo: NETWORK_FILTER
---
apiVersion: v1
kind: ConfigMap
metadata:
name: istio-version
annotations:
config.kubernetes.io/local-config: true
data:
ISTIO_REGEX: '^1\.14.*'
`,
replacements: `
replacements:
- source:
kind: ConfigMap
name: istio-version
fieldPath: data.ISTIO_REGEX
targets:
- select:
kind: EnvoyFilter
fieldPaths:
- spec.configPatches.0.match.proxy.proxyVersion
- spec.configPatches.1.match.proxy.proxyVersion
- spec.configPatches.2.match.proxy.proxyVersion
- spec.configPatches.3.match.proxy.proxyVersion
options:
create: true
`,
expected: `
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: request-id
spec:
configPatches:
- applyTo: NETWORK_FILTER
match:
proxy:
proxyVersion: ^1\.14.*
- applyTo: NETWORK_FILTER
match:
proxy:
proxyVersion: ^1\.14.*
- match:
proxy:
proxyVersion: ^1\.14.*
- match:
proxy:
proxyVersion: ^1\.14.*
---
apiVersion: v1
kind: ConfigMap
metadata:
name: istio-version
annotations:
config.kubernetes.io/local-config: true
data:
ISTIO_REGEX: '^1\.14.*'
`,
},
"issue4761 - path not in target with create: false": {
input: `
---
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: request-id
spec:
configPatches:
- applyTo: NETWORK_FILTER
- applyTo: NETWORK_FILTER
---
apiVersion: v1
kind: ConfigMap
metadata:
name: istio-version
annotations:
config.kubernetes.io/local-config: true
data:
ISTIO_REGEX: '^1\.14.*'
`,
replacements: `
replacements:
- source:
kind: ConfigMap
name: istio-version
fieldPath: data.ISTIO_REGEX
targets:
- select:
kind: EnvoyFilter
fieldPaths:
- spec.configPatches.0.match.proxy.proxyVersion
- spec.configPatches.1.match.proxy.proxyVersion
- spec.configPatches.2.match.proxy.proxyVersion
- spec.configPatches.3.match.proxy.proxyVersion
options:
create: false
`,
expectedErr: "unable to find field \"spec.configPatches.0.match.proxy.proxyVersion\" in replacement target",
},
"issue4761 - wildcard solution": {
input: `
---
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: request-id
spec:
configPatches:
- applyTo: NETWORK_FILTER
- applyTo: NETWORK_FILTER
---
apiVersion: v1
kind: ConfigMap
metadata:
name: istio-version
annotations:
config.kubernetes.io/local-config: true
data:
ISTIO_REGEX: '^1\.14.*'
`,
replacements: `
replacements:
- source:
kind: ConfigMap
name: istio-version
fieldPath: data.ISTIO_REGEX
targets:
- select:
kind: EnvoyFilter
fieldPaths:
- spec.configPatches.*.match.proxy.proxyVersion
options:
create: true
`,
expected: `
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: request-id
spec:
configPatches:
- applyTo: NETWORK_FILTER
match:
proxy:
proxyVersion: ^1\.14.*
- applyTo: NETWORK_FILTER
match:
proxy:
proxyVersion: ^1\.14.*
---
apiVersion: v1
kind: ConfigMap
metadata:
name: istio-version
annotations:
config.kubernetes.io/local-config: true
data:
ISTIO_REGEX: '^1\.14.*'
`,
},
"append to sequence using index": {
input: `apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myingress
spec:
rules:
- host: myingress.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-svc
port:
number: 80
`,
replacements: `replacements:
- source:
kind: Ingress
name: myingress
fieldPath: spec.rules.0.host
targets:
- select:
kind: Ingress
name: myingress
fieldPaths:
- spec.tls.0.hosts.0
- spec.tls.0.secretName
options:
create: true
`,
expected: `apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myingress
spec:
rules:
- host: myingress.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-svc
port:
number: 80
tls:
- hosts:
- myingress.example.com
secretName: myingress.example.com`,
},
"fail to append to sequence using a distant index": {
input: `apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myingress
spec:
rules:
- host: myingress.example.com
`,
replacements: `replacements:
- source:
kind: Ingress
name: myingress
fieldPath: spec.rules.0.host
targets:
- select:
kind: Ingress
name: myingress
fieldPaths:
- spec.tls.5.hosts.5
- spec.tls.5.secretName
options:
create: true
`,
expectedErr: "unable to find or create field \"spec.tls.5.hosts.5\" in replacement target: index 5 specified but only 0 elements found",
},
}
for tn, tc := range testCases {

View File

@@ -1,16 +1,37 @@
module sigs.k8s.io/kustomize/api
go 1.16
go 1.20
require (
github.com/evanphx/json-patch v4.11.0+incompatible
github.com/go-errors/errors v1.0.1
github.com/go-errors/errors v1.4.2
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
github.com/imdario/mergo v0.3.5
github.com/pkg/errors v0.9.1
github.com/stretchr/testify v1.7.0
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-20220401212409-b28bf2818661
sigs.k8s.io/kustomize/kyaml v0.13.7
sigs.k8s.io/yaml v1.2.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.2 // indirect
github.com/go-openapi/swag v0.22.3 // 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.2.0 // indirect
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // 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
)

View File

@@ -1,656 +1,92 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=
cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=
cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg=
cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8=
cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM=
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/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
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/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
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/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/getkin/kin-openapi v0.76.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSyhcnluiMv+Xg=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w=
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY=
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/jsonreference v0.19.3 h1:5cxNfTy0UVC3X8JL5ymxzyoUZmo8iZb+jeTWn7tUa8o=
github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY=
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
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.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
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.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/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=
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/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/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.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4/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.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g=
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
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/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/imdario/mergo v0.3.5 h1:JboBksRwiiAJWvIYJVo46AfV+IAIKZpfrSzVKj42R4Q=
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
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 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs=
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
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 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.7.0 h1:aizVhC/NAAcKWb+5QsU1iNOZb4Yws5UO2I+aIprQITM=
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0=
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4=
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
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/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
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/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk=
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns=
github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
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.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca h1:1CFlNzQhALwjS9mBAUkycX616GzgsuYUOCHA5+HSlXI=
github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs=
go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
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.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=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo=
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
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-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
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-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/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/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 h1:4nGaVu0QrbjT/AK2PRLuQfQuh6DJve+pELhqTdAj3x0=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
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-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/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-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191002063906-3421d5a6bb1c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
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-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
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 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU=
google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94=
google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8=
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/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
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.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.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
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-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
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.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/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-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/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-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
k8s.io/kube-openapi v0.0.0-20220401212409-b28bf2818661 h1:nqYOUleKLC/0P1zbU29F5q6aoezM6MOAVz+iyfQbZ5M=
k8s.io/kube-openapi v0.0.0-20220401212409-b28bf2818661/go.mod h1:daOouuuwd9JXpv1L7Y34iV3yf6nxzipkKMWWlqlvK9M=
k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
sigs.k8s.io/kustomize/kyaml v0.13.7 h1:/EZ/nPaLUzeJKF/BuJ4QCuMVJWiEVoI8iftOHY3g3tk=
sigs.k8s.io/kustomize/kyaml v0.13.7/go.mod h1:6K+IUOuir3Y7nucPRAjw9yth04KSWBnP5pqUTGwj/qU=
sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
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=
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=

View File

@@ -28,12 +28,20 @@ type KvLoader interface {
// Loader interface exposes methods to read bytes.
type Loader interface {
// Repo returns the repo location if this Loader was created from a url
// or the empty string otherwise.
Repo() string
// Root returns the root location for this Loader.
Root() string
// New returns Loader located at newRoot.
New(newRoot string) (Loader, error)
// Load returns the bytes read from the location or an error.
Load(location string) ([]byte, error)
// Cleanup cleans the loader
Cleanup() error
}

View File

@@ -7,11 +7,11 @@ import (
"encoding/json"
"strings"
"github.com/pkg/errors"
"k8s.io/kube-openapi/pkg/validation/spec"
"sigs.k8s.io/kustomize/api/ifc"
"sigs.k8s.io/kustomize/api/internal/plugins/builtinconfig"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/errors"
"sigs.k8s.io/kustomize/kyaml/filesys"
"sigs.k8s.io/kustomize/kyaml/resid"
"sigs.k8s.io/yaml"
@@ -39,7 +39,7 @@ func LoadConfigFromCRDs(
}
m, err := makeNameToApiMap(content)
if err != nil {
return nil, errors.Wrapf(err, "unable to parse open API definition from '%s'", path)
return nil, errors.WrapPrefixf(err, "unable to parse open API definition from '%s'", path)
}
otherTc, err := makeConfigFromApiMap(m)
if err != nil {

View File

@@ -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"

View File

@@ -7,6 +7,7 @@ import (
"strings"
"testing"
"github.com/stretchr/testify/require"
"sigs.k8s.io/kustomize/api/internal/plugins/builtinconfig"
"sigs.k8s.io/kustomize/api/provider"
"sigs.k8s.io/kustomize/api/resmap"
@@ -524,6 +525,52 @@ func TestNameReferenceUnhappyRun(t *testing.T) {
`considering field 'rules/resourceNames' of object ClusterRole.v1.rbac.authorization.k8s.io/cr.[noNs]: visit traversal on ` +
`path: [resourceNames]: path config error; no 'name' field in node`,
},
{
// When targeting a map reference, we need to update both name and namespace, so multiple
// possible referral targets with different namespaces should not be considered identical.
// This test covers a bug where the difference in namespace was ignored and one candidate was chosen at random.
resMap: resmaptest_test.NewRmBuilderDefault(t).AddWithNsAndName(
"", orgname,
map[string]interface{}{
"apiVersion": "v1",
"kind": "ServiceAccount",
"metadata": map[string]interface{}{
"name": orgname,
"namespace": ns1,
},
},
).AddWithNsAndName(
"", orgname,
map[string]interface{}{
"apiVersion": "v1",
"kind": "ServiceAccount",
"metadata": map[string]interface{}{
"name": orgname,
"namespace": ns2,
},
},
).Add(
map[string]interface{}{
"apiVersion": "rbac.authorization.k8s.io/v1",
"kind": "ClusterRoleBinding",
"metadata": map[string]interface{}{
"name": orgname,
},
"roleRef": map[string]interface{}{
"apiGroup": "rbac.authorization.k8s.io",
"kind": "ClusterRole",
"name": orgname,
},
"subjects": []interface{}{
map[string]interface{}{
"kind": "ServiceAccount",
"name": orgname,
},
},
},
).ResMap(),
expectedErr: "found multiple possible referrals: ServiceAccount.v1.[noGrp]/uniquename.ns1, ServiceAccount.v1.[noGrp]/uniquename.ns2",
},
}
nrt := newNameReferenceTransformer(builtinconfig.MakeDefaultConfig().NameReference)
@@ -1061,3 +1108,76 @@ func TestNameReferenceCandidateSelection(t *testing.T) {
t.Fatalf(notEqualErrFmt, err)
}
}
func TestNameReferenceCandidateDisambiguationByNamespace(t *testing.T) {
// The ClusterRole refers to both configmaps, since it is not namespace-specific.
// Since both names are updated consistently, the transformer should be able to
// silently update the ClusterRole as well.
// This test guards against a regression where allNamesAndNamespacesAreTheSame would be
// used to detect referral candidate identity instead of allNamesAreTheSame.
m := resmaptest_test.NewRmBuilderDefault(t).AddWithName(orgname,
map[string]interface{}{
"apiVersion": "v1",
"kind": "ConfigMap",
"metadata": map[string]interface{}{
"name": suffixedname,
"namespace": ns1,
},
},
).AddWithName(orgname,
map[string]interface{}{
"apiVersion": "v1",
"kind": "ConfigMap",
"metadata": map[string]interface{}{
"name": suffixedname,
"namespace": ns2,
},
},
).Add(
map[string]interface{}{
"apiVersion": "rbac.authorization.k8s.io/v1",
"kind": "ClusterRole",
"metadata": map[string]interface{}{
"name": orgname,
},
"rules": []interface{}{
map[string]interface{}{
"resources": []interface{}{
"configmaps",
},
"resourceNames": []interface{}{
orgname,
},
},
},
},
).ResMap()
expected := resmaptest_test.NewSeededRmBuilderDefault(t, m.ShallowCopy()).
ReplaceResource(map[string]interface{}{
"apiVersion": "rbac.authorization.k8s.io/v1",
"kind": "ClusterRole",
"metadata": map[string]interface{}{
"name": orgname,
},
"rules": []interface{}{
map[string]interface{}{
"resources": []interface{}{
"configmaps",
},
"resourceNames": []interface{}{
suffixedname,
},
},
},
},
).ResMap()
nrt := newNameReferenceTransformer(builtinconfig.MakeDefaultConfig().NameReference)
require.NoError(t, nrt.Transform(m))
m.RemoveBuildAnnotations()
if err := expected.ErrorIfNotEqualLists(m); err != nil {
t.Fatalf(notEqualErrFmt, err)
}
}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -1,12 +1,11 @@
// Code generated by pluginator on HelmChartInflationGenerator; DO NOT EDIT.
// pluginator {unknown 1970-01-01T00:00:00Z }
// pluginator {(devel) unknown }
package builtins
import (
"bytes"
"fmt"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
@@ -14,14 +13,14 @@ import (
"strings"
"github.com/imdario/mergo"
"github.com/pkg/errors"
"sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/errors"
"sigs.k8s.io/kustomize/kyaml/kio"
"sigs.k8s.io/yaml"
)
// HelmChartInflationGeneratorPlugin is a plugin to generate resources
// from a remote or local helm chart.
// Generate resources from a remote or local helm chart.
type HelmChartInflationGeneratorPlugin struct {
h *resmap.PluginHelpers
types.HelmGlobals
@@ -29,8 +28,6 @@ type HelmChartInflationGeneratorPlugin struct {
tmpDir string
}
var KustomizePlugin HelmChartInflationGeneratorPlugin
const (
valuesMergeOptionMerge = "merge"
valuesMergeOptionOverride = "override"
@@ -73,7 +70,7 @@ func (p *HelmChartInflationGeneratorPlugin) establishTmpDir() (err error) {
// already done.
return nil
}
p.tmpDir, err = ioutil.TempDir("", "kustomize-helm-")
p.tmpDir, err = os.MkdirTemp("", "kustomize-helm-")
return err
}
@@ -87,15 +84,23 @@ func (p *HelmChartInflationGeneratorPlugin) validateArgs() (err error) {
// the loader root (unless root restrictions are
// disabled, in which case this can be an absolute path).
if p.ChartHome == "" {
p.ChartHome = "charts"
p.ChartHome = types.HelmDefaultHome
}
// The ValuesFile may be consulted by the plugin, so it must
// The ValuesFile(s) may be consulted by the plugin, so it must
// be under the loader root (unless root restrictions are
// disabled).
if p.ValuesFile == "" {
p.ValuesFile = filepath.Join(p.ChartHome, p.Name, "values.yaml")
}
for i, file := range p.AdditionalValuesFiles {
// use Load() to enforce root restrictions
if _, err := p.h.Loader().Load(file); err != nil {
return errors.WrapPrefixf(err, "could not load additionalValuesFile")
}
// the additional values filepaths must be relative to the kust root
p.AdditionalValuesFiles[i] = filepath.Join(p.h.Loader().Root(), file)
}
if err = p.errIfIllegalValuesMerge(); err != nil {
return err
@@ -104,7 +109,7 @@ func (p *HelmChartInflationGeneratorPlugin) validateArgs() (err error) {
// ConfigHome is not loaded by the plugin, and can be located anywhere.
if p.ConfigHome == "" {
if err = p.establishTmpDir(); err != nil {
return errors.Wrap(
return errors.WrapPrefixf(
err, "unable to create tmp dir for HELM_CONFIG_HOME")
}
p.ConfigHome = filepath.Join(p.tmpDir, "helm")
@@ -148,10 +153,10 @@ func (p *HelmChartInflationGeneratorPlugin) runHelmCommand(
err := cmd.Run()
if err != nil {
helm := p.h.GeneralConfig().HelmConfig.Command
err = errors.Wrap(
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(),
)
}
@@ -211,7 +216,7 @@ func (p *HelmChartInflationGeneratorPlugin) writeValuesBytes(
return "", fmt.Errorf("cannot create tmp dir to write helm values")
}
path := filepath.Join(p.tmpDir, p.Name+"-kustomize-values.yaml")
return path, ioutil.WriteFile(path, b, 0644)
return path, errors.WrapPrefixf(os.WriteFile(path, b, 0644), "failed to write values file")
}
func (p *HelmChartInflationGeneratorPlugin) cleanup() {
@@ -244,46 +249,31 @@ func (p *HelmChartInflationGeneratorPlugin) Generate() (rm resmap.ResMap, err er
return nil, err
}
var stdout []byte
stdout, err = p.runHelmCommand(p.templateCommand())
stdout, err = p.runHelmCommand(p.AsHelmArgs(p.absChartHome()))
if err != nil {
return nil, err
}
rm, err = p.h.ResmapFactory().NewResMapFromBytes(stdout)
if err == nil {
rm, resMapErr := p.h.ResmapFactory().NewResMapFromBytes(stdout)
if resMapErr == nil {
return rm, nil
}
// try to remove the contents before first "---" because
// helm may produce messages to stdout before it
stdoutStr := string(stdout)
if idx := strings.Index(stdoutStr, "---"); idx != -1 {
return p.h.ResmapFactory().NewResMapFromBytes([]byte(stdoutStr[idx:]))
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)
}
return nil, err
}
func (p *HelmChartInflationGeneratorPlugin) templateCommand() []string {
args := []string{"template"}
if p.ReleaseName != "" {
args = append(args, p.ReleaseName)
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", err)
}
return rm, nil
}
if p.Namespace != "" {
args = append(args, "--namespace", p.Namespace)
}
args = append(args, filepath.Join(p.absChartHome(), p.Name))
if p.ValuesFile != "" {
args = append(args, "--values", p.ValuesFile)
}
if p.ReleaseName == "" {
// AFAICT, this doesn't work as intended due to a bug in helm.
// See https://github.com/helm/helm/issues/6019
// I've tried placing the flag before and after the name argument.
args = append(args, "--generate-name")
}
if p.IncludeCRDs {
args = append(args, "--include-crds")
}
return args
return nil, fmt.Errorf("could not parse bytes into resource map: %w", resMapErr)
}
func (p *HelmChartInflationGeneratorPlugin) pullCommand() []string {
@@ -291,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)
}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -1,46 +0,0 @@
// Code generated by pluginator on LegacyOrderTransformer; DO NOT EDIT.
// pluginator {unknown 1970-01-01T00:00:00Z }
package builtins
import (
"sort"
"github.com/pkg/errors"
"sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/resource"
)
// Sort the resources using an ordering defined in the Gvk class.
// This puts cluster-wide basic resources with no
// dependencies (like Namespace, StorageClass, etc.)
// first, and resources with a high number of dependencies
// (like ValidatingWebhookConfiguration) last.
type LegacyOrderTransformerPlugin struct{}
// Nothing needed for configuration.
func (p *LegacyOrderTransformerPlugin) Config(
_ *resmap.PluginHelpers, _ []byte) (err error) {
return nil
}
func (p *LegacyOrderTransformerPlugin) Transform(m resmap.ResMap) (err error) {
resources := make([]*resource.Resource, m.Size())
ids := m.AllIds()
sort.Sort(resmap.IdSlice(ids))
for i, id := range ids {
resources[i], err = m.GetByCurrentId(id)
if err != nil {
return errors.Wrap(err, "expected match for sorting")
}
}
m.Clear()
for _, r := range resources {
m.Append(r)
}
return nil
}
func NewLegacyOrderTransformerPlugin() resmap.TransformerPlugin {
return &LegacyOrderTransformerPlugin{}
}

View File

@@ -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
@@ -9,20 +9,37 @@ import (
"sigs.k8s.io/kustomize/api/filters/namespace"
"sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/errors"
"sigs.k8s.io/yaml"
)
// Change or set the namespace of non-cluster level resources.
type NamespaceTransformerPlugin struct {
types.ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
FieldSpecs []types.FieldSpec `json:"fieldSpecs,omitempty" yaml:"fieldSpecs,omitempty"`
types.ObjectMeta `json:"metadata,omitempty" yaml:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
FieldSpecs []types.FieldSpec `json:"fieldSpecs,omitempty" yaml:"fieldSpecs,omitempty"`
UnsetOnly bool `json:"unsetOnly" yaml:"unsetOnly"`
SetRoleBindingSubjects namespace.RoleBindingSubjectMode `json:"setRoleBindingSubjects" yaml:"setRoleBindingSubjects"`
}
func (p *NamespaceTransformerPlugin) Config(
_ *resmap.PluginHelpers, c []byte) (err error) {
p.Namespace = ""
p.FieldSpecs = nil
return yaml.Unmarshal(c, p)
if err := yaml.Unmarshal(c, p); err != nil {
return errors.WrapPrefixf(err, "unmarshalling NamespaceTransformer config")
}
switch p.SetRoleBindingSubjects {
case namespace.AllServiceAccountSubjects, namespace.DefaultSubjectsOnly, namespace.NoSubjects:
// valid
case namespace.SubjectModeUnspecified:
p.SetRoleBindingSubjects = namespace.DefaultSubjectsOnly
default:
return errors.Errorf("invalid value %q for setRoleBindingSubjects: "+
"must be one of %q, %q or %q", p.SetRoleBindingSubjects,
namespace.DefaultSubjectsOnly, namespace.NoSubjects, namespace.AllServiceAccountSubjects)
}
return nil
}
func (p *NamespaceTransformerPlugin) Transform(m resmap.ResMap) error {
@@ -36,8 +53,10 @@ func (p *NamespaceTransformerPlugin) Transform(m resmap.ResMap) error {
}
r.StorePreviousId()
if err := r.ApplyFilter(namespace.Filter{
Namespace: p.Namespace,
FsSlice: p.FieldSpecs,
Namespace: p.Namespace,
FsSlice: p.FieldSpecs,
SetRoleBindingSubjects: p.SetRoleBindingSubjects,
UnsetOnly: p.UnsetOnly,
}); err != nil {
return err
}

View File

@@ -1,17 +1,17 @@
// 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"
"github.com/pkg/errors"
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"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/errors"
"sigs.k8s.io/kustomize/kyaml/kio/kioutil"
"sigs.k8s.io/yaml"
)
@@ -61,7 +61,7 @@ func (p *PatchJson6902TransformerPlugin) Config(
}
p.decodedPatch, err = jsonpatch.DecodePatch([]byte(p.JsonOp))
if err != nil {
return errors.Wrapf(err, "decoding %s", p.JsonOp)
return errors.WrapPrefixf(err, "decoding %s", p.JsonOp)
}
if len(p.decodedPatch) == 0 {
return fmt.Errorf(

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,244 @@
// Code generated by pluginator on SortOrderTransformer; DO NOT EDIT.
// pluginator {(devel) unknown }
package builtins
import (
"sort"
"strings"
"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/resid"
"sigs.k8s.io/yaml"
)
// Sort the resources using a customizable ordering based of Kind.
// Defaults to the ordering of the GVK struct, which puts cluster-wide basic
// resources with no dependencies (like Namespace, StorageClass, etc.) first,
// and resources with a high number of dependencies
// (like ValidatingWebhookConfiguration) last.
type SortOrderTransformerPlugin struct {
SortOptions *types.SortOptions `json:"sortOptions,omitempty" yaml:"sortOptions,omitempty"`
}
func (p *SortOrderTransformerPlugin) Config(
_ *resmap.PluginHelpers, c []byte) error {
return errors.WrapPrefixf(yaml.Unmarshal(c, p), "Failed to unmarshal SortOrderTransformer config")
}
func (p *SortOrderTransformerPlugin) applyDefaults() {
// Default to FIFO sort, aka no-op.
if p.SortOptions == nil {
p.SortOptions = &types.SortOptions{
Order: types.FIFOSortOrder,
}
}
// If legacy sort is selected and no options are given, default to
// hardcoded order.
if p.SortOptions.Order == types.LegacySortOrder && p.SortOptions.LegacySortOptions == nil {
p.SortOptions.LegacySortOptions = &types.LegacySortOptions{
OrderFirst: defaultOrderFirst,
OrderLast: defaultOrderLast,
}
}
}
func (p *SortOrderTransformerPlugin) validate() error {
// Check valid values for SortOrder
if p.SortOptions.Order != types.FIFOSortOrder && p.SortOptions.Order != types.LegacySortOrder {
return errors.Errorf("the field 'sortOptions.order' must be one of [%s, %s]",
types.FIFOSortOrder, types.LegacySortOrder)
}
// Validate that the only options set are the ones corresponding to the
// selected sort order.
if p.SortOptions.Order == types.FIFOSortOrder &&
p.SortOptions.LegacySortOptions != nil {
return errors.Errorf("the field 'sortOptions.legacySortOptions' is"+
" set but the selected sort order is '%v', not 'legacy'",
p.SortOptions.Order)
}
return nil
}
func (p *SortOrderTransformerPlugin) Transform(m resmap.ResMap) (err error) {
p.applyDefaults()
err = p.validate()
if err != nil {
return err
}
// Sort
if p.SortOptions.Order == types.LegacySortOrder {
s := newLegacyIDSorter(m.AllIds(), p.SortOptions.LegacySortOptions)
sort.Sort(s)
err = applyOrdering(m, s.resids)
if err != nil {
return err
}
}
return nil
}
// applyOrdering takes resources (given in ResMap) and a desired ordering given
// as a sequence of ResIds, and updates the ResMap's resources to match the
// ordering.
func applyOrdering(m resmap.ResMap, ordering []resid.ResId) error {
var err error
resources := make([]*resource.Resource, m.Size())
// Clear and refill with the correct order
for i, id := range ordering {
resources[i], err = m.GetByCurrentId(id)
if err != nil {
return errors.WrapPrefixf(err, "expected match for sorting")
}
}
m.Clear()
for _, r := range resources {
err = m.Append(r)
if err != nil {
return errors.WrapPrefixf(err, "SortOrderTransformer: Failed to append to resources")
}
}
return nil
}
// Code for legacy sorting.
// Legacy sorting is a "fixed" order sorting maintained for backwards
// compatibility.
// legacyIDSorter sorts resources based on two priority lists:
// - orderFirst: Resources that should be placed in the start, in the given order.
// - orderLast: Resources that should be placed in the end, in the given order.
type legacyIDSorter struct {
// resids only stores the metadata of the object. This is an optimization as
// it's expensive to compute these again and again during ordering.
resids []resid.ResId
typeOrders map[string]int
}
func newLegacyIDSorter(
resids []resid.ResId,
options *types.LegacySortOptions) *legacyIDSorter {
// Precalculate a resource ranking based on the priority lists.
var typeOrders = func() map[string]int {
m := map[string]int{}
for i, n := range options.OrderFirst {
m[n] = -len(options.OrderFirst) + i
}
for i, n := range options.OrderLast {
m[n] = 1 + i
}
return m
}()
return &legacyIDSorter{
resids: resids,
typeOrders: typeOrders,
}
}
var _ sort.Interface = legacyIDSorter{}
func (a legacyIDSorter) Len() int { return len(a.resids) }
func (a legacyIDSorter) Swap(i, j int) {
a.resids[i], a.resids[j] = a.resids[j], a.resids[i]
}
func (a legacyIDSorter) Less(i, j int) bool {
if !a.resids[i].Gvk.Equals(a.resids[j].Gvk) {
return gvkLessThan(a.resids[i].Gvk, a.resids[j].Gvk, a.typeOrders)
}
return legacyResIDSortString(a.resids[i]) < legacyResIDSortString(a.resids[j])
}
func gvkLessThan(gvk1, gvk2 resid.Gvk, typeOrders map[string]int) bool {
index1 := typeOrders[gvk1.Kind]
index2 := typeOrders[gvk2.Kind]
if index1 != index2 {
return index1 < index2
}
return legacyGVKSortString(gvk1) < legacyGVKSortString(gvk2)
}
// legacyGVKSortString returns a string representation of given GVK used for
// stable sorting.
func legacyGVKSortString(x resid.Gvk) string {
legacyNoGroup := "~G"
legacyNoVersion := "~V"
legacyNoKind := "~K"
legacyFieldSeparator := "_"
g := x.Group
if g == "" {
g = legacyNoGroup
}
v := x.Version
if v == "" {
v = legacyNoVersion
}
k := x.Kind
if k == "" {
k = legacyNoKind
}
return strings.Join([]string{g, v, k}, legacyFieldSeparator)
}
// legacyResIDSortString returns a string representation of given ResID used for
// stable sorting.
func legacyResIDSortString(id resid.ResId) string {
legacyNoNamespace := "~X"
legacyNoName := "~N"
legacySeparator := "|"
ns := id.Namespace
if ns == "" {
ns = legacyNoNamespace
}
nm := id.Name
if nm == "" {
nm = legacyNoName
}
return strings.Join(
[]string{id.Gvk.String(), ns, nm}, legacySeparator)
}
// DO NOT CHANGE!
// Final legacy ordering provided as a default by kustomize.
// Originally an attempt to apply resources in the correct order, an effort
// which later proved impossible as not all types are known beforehand.
// See: https://github.com/kubernetes-sigs/kustomize/issues/3913
var defaultOrderFirst = []string{ //nolint:gochecknoglobals
"Namespace",
"ResourceQuota",
"StorageClass",
"CustomResourceDefinition",
"ServiceAccount",
"PodSecurityPolicy",
"Role",
"ClusterRole",
"RoleBinding",
"ClusterRoleBinding",
"ConfigMap",
"Secret",
"Endpoints",
"Service",
"LimitRange",
"PriorityClass",
"PersistentVolume",
"PersistentVolumeClaim",
"Deployment",
"StatefulSet",
"CronJob",
"PodDisruptionBudget",
}
var defaultOrderLast = []string{ //nolint:gochecknoglobals
"MutatingWebhookConfiguration",
"ValidatingWebhookConfiguration",
}
func NewSortOrderTransformerPlugin() resmap.TransformerPlugin {
return &SortOrderTransformerPlugin{}
}

View File

@@ -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

View File

@@ -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

View File

@@ -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"

View File

@@ -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"

View File

@@ -5,6 +5,8 @@ package generators
import (
"fmt"
"path"
"strings"
"github.com/go-errors/errors"
"sigs.k8s.io/kustomize/api/ifc"
@@ -95,3 +97,28 @@ func setImmutable(
return nil
}
// ParseFileSource parses the source given.
//
// Acceptable formats include:
// 1. source-path: the basename will become the key name
// 2. source-name=source-path: the source-name will become the key name and
// source-path is the path to the key file.
//
// Key names cannot include '='.
func ParseFileSource(source string) (keyName, filePath string, err error) {
numSeparators := strings.Count(source, "=")
switch {
case numSeparators == 0:
return path.Base(source), source, nil
case numSeparators == 1 && strings.HasPrefix(source, "="):
return "", "", errors.Errorf("missing key name for file path %q in source %q", strings.TrimPrefix(source, "="), source)
case numSeparators == 1 && strings.HasSuffix(source, "="):
return "", "", errors.Errorf("missing file path for key name %q in source %q", strings.TrimSuffix(source, "="), source)
case numSeparators > 1:
return "", "", errors.Errorf("source %q key name or file path contains '='", source)
default:
components := strings.Split(source, "=")
return components[0], components[1], nil
}
}

View File

@@ -0,0 +1,51 @@
// Copyright 2020 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package generators_test
import (
"testing"
"github.com/stretchr/testify/require"
. "sigs.k8s.io/kustomize/api/internal/generators"
)
func TestParseFileSource(t *testing.T) {
tests := map[string]*struct {
Input string
Error string
Key string
Filename string
}{
"filename only": {
Input: "./path/myfile",
Key: "myfile",
Filename: "./path/myfile",
},
"key and filename": {
Input: "newName.ini=oldName",
Key: "newName.ini",
Filename: "oldName",
},
"multiple =": {
Input: "newName.ini==oldName",
Error: `source "newName.ini==oldName" key name or file path contains '='`,
},
"missing key": {
Input: "=myfile",
Error: `missing key name for file path "myfile" in source "=myfile"`,
},
}
for name, test := range tests {
t.Run(name, func(t *testing.T) {
key, file, err := ParseFileSource(test.Input)
if test.Error != "" {
require.EqualError(t, err, test.Error)
} else {
require.NoError(t, err)
require.Equal(t, test.Key, key)
require.Equal(t, test.Filename, file)
}
})
}
}

View File

@@ -22,15 +22,17 @@ func ClonerUsingGitExec(repoSpec *RepoSpec) error {
if err = r.run("init"); err != nil {
return err
}
if err = r.run(
"remote", "add", "origin", repoSpec.CloneSpec()); err != nil {
// 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
}
if err = r.run("fetch", "--depth=1", "origin", ref); err != nil {
// 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
}
if err = r.run("checkout", "FETCH_HEAD"); err != nil {

View File

@@ -7,8 +7,8 @@ import (
"os/exec"
"time"
"github.com/pkg/errors"
"sigs.k8s.io/kustomize/api/internal/utils"
"sigs.k8s.io/kustomize/kyaml/errors"
"sigs.k8s.io/kustomize/kyaml/filesys"
)
@@ -24,7 +24,7 @@ type gitRunner struct {
func newCmdRunner(timeout time.Duration) (*gitRunner, error) {
gitProgram, err := exec.LookPath("git")
if err != nil {
return nil, errors.Wrap(err, "no 'git' program on path")
return nil, errors.WrapPrefixf(err, "no 'git' program on path")
}
dir, err := filesys.NewTmpConfirmedDir()
if err != nil {
@@ -46,9 +46,9 @@ func (r gitRunner) run(args ...string) error {
cmd.String(),
r.duration,
func() error {
_, err := cmd.CombinedOutput()
out, err := cmd.CombinedOutput()
if err != nil {
return errors.Wrapf(err, "git cmd = '%s'", cmd.String())
return errors.WrapPrefixf(err, "failed to run '%s': %s", cmd.String(), string(out))
}
return err
})

View File

@@ -5,12 +5,15 @@ package git
import (
"fmt"
"log"
"net/url"
"path/filepath"
"regexp"
"strconv"
"strings"
"time"
"sigs.k8s.io/kustomize/kyaml/errors"
"sigs.k8s.io/kustomize/kyaml/filesys"
)
@@ -27,26 +30,23 @@ type RepoSpec struct {
// TODO(monopole): Drop raw, use processed fields instead.
raw string
// Host, e.g. github.com
// Host, e.g. https://github.com/
Host string
// orgRepo name (organization/repoName),
// RepoPath name (Path to repository),
// e.g. kubernetes-sigs/kustomize
OrgRepo string
RepoPath string
// Dir where the orgRepo is cloned to.
// Dir is where the repository is cloned to.
Dir filesys.ConfirmedDir
// Relative path in the repository, and in the cloneDir,
// to a Kustomization.
Path string
KustRootPath string
// Branch or tag reference.
Ref string
// e.g. .git or empty in case of _git is present
GitSuffix string
// Submodules indicates whether or not to clone git submodules.
Submodules bool
@@ -56,10 +56,7 @@ type RepoSpec struct {
// CloneSpec returns a string suitable for "git clone {spec}".
func (x *RepoSpec) CloneSpec() string {
if isAzureHost(x.Host) || isAWSHost(x.Host) {
return x.Host + x.OrgRepo
}
return x.Host + x.OrgRepo + x.GitSuffix
return x.Host + x.RepoPath
}
func (x *RepoSpec) CloneDir() filesys.ConfirmedDir {
@@ -71,81 +68,140 @@ func (x *RepoSpec) Raw() string {
}
func (x *RepoSpec) AbsPath() string {
return x.Dir.Join(x.Path)
return x.Dir.Join(x.KustRootPath)
}
func (x *RepoSpec) Cleaner(fSys filesys.FileSystem) func() error {
return func() error { return fSys.RemoveAll(x.Dir.String()) }
}
const (
refQuery = "?ref="
gitSuffix = ".git"
gitRootDelimiter = "_git/"
pathSeparator = "/" // do not use filepath.Separator, as this is a URL
)
// NewRepoSpecFromURL parses git-like urls.
// From strings like git@github.com:someOrg/someRepo.git or
// https://github.com/someOrg/someRepo?ref=someHash, extract
// the parts.
// the different parts of URL, set into a RepoSpec object and return RepoSpec object.
// It MUST return an error if the input is not a git-like URL, as this is used by some code paths
// to distinguish between local and remote paths.
//
// In particular, NewRepoSpecFromURL separates the URL used to clone the repo from the
// elements Kustomize uses for other purposes (e.g. query params that turn into args, and
// the path to the kustomization root within the repo).
func NewRepoSpecFromURL(n string) (*RepoSpec, error) {
repoSpec := &RepoSpec{raw: n, Dir: notCloned, Timeout: defaultTimeout, Submodules: defaultSubmodules}
if filepath.IsAbs(n) {
return nil, fmt.Errorf("uri looks like abs path: %s", n)
}
host, orgRepo, path, gitRef, gitSubmodules, suffix, gitTimeout := parseGitURL(n)
if orgRepo == "" {
return nil, fmt.Errorf("url lacks orgRepo: %s", n)
// Parse the query first. This is safe because according to rfc3986 "?" is only allowed in the
// query and is not recognized %-encoded.
// Note that parseQuery returns default values for empty parameters.
n, query, _ := strings.Cut(n, "?")
repoSpec.Ref, repoSpec.Timeout, repoSpec.Submodules = parseQuery(query)
var err error
// Parse the host (e.g. scheme, username, domain) segment.
repoSpec.Host, n, err = extractHost(n)
if err != nil {
return nil, err
}
if host == "" {
return nil, fmt.Errorf("url lacks host: %s", n)
// In some cases, we're given a path to a git repo + a path to the kustomization root within
// that repo. We need to split them so that we can ultimately give the repo only to the cloner.
repoSpec.RepoPath, repoSpec.KustRootPath, err = parsePathParts(n, defaultRepoPathLength(repoSpec.Host))
if err != nil {
return nil, err
}
return &RepoSpec{
raw: n, Host: host, OrgRepo: orgRepo,
Dir: notCloned, Path: path, Ref: gitRef, GitSuffix: suffix,
Submodules: gitSubmodules, Timeout: gitTimeout}, nil
return repoSpec, nil
}
const (
refQuery = "?ref="
gitSuffix = ".git"
gitDelimiter = "_git/"
)
const allSegments = -999999
const orgRepoSegments = 2
// From strings like git@github.com:someOrg/someRepo.git or
// https://github.com/someOrg/someRepo?ref=someHash, extract
// the parts.
func parseGitURL(n string) (
host string, orgRepo string, path string, gitRef string, gitSubmodules bool, gitSuff string, gitTimeout time.Duration) {
if strings.Contains(n, gitDelimiter) {
index := strings.Index(n, gitDelimiter)
// Adding _git/ to host
host = normalizeGitHostSpec(n[:index+len(gitDelimiter)])
orgRepo = strings.Split(strings.Split(n[index+len(gitDelimiter):], "/")[0], "?")[0]
path, gitRef, gitTimeout, gitSubmodules = peelQuery(n[index+len(gitDelimiter)+len(orgRepo):])
return
func defaultRepoPathLength(host string) int {
if strings.HasPrefix(host, fileScheme) {
return allSegments
}
host, n = parseHostSpec(n)
gitSuff = gitSuffix
if strings.Contains(n, gitSuffix) {
index := strings.Index(n, gitSuffix)
orgRepo = n[0:index]
n = n[index+len(gitSuffix):]
if len(n) > 0 && n[0] == '/' {
n = n[1:]
}
path, gitRef, gitTimeout, gitSubmodules = peelQuery(n)
return
return orgRepoSegments
}
// parsePathParts splits the repo path that will ultimately be passed to git to clone the
// repo from the kustomization root path, which Kustomize will execute the build in after the repo
// is cloned.
//
// We first try to do this based on explicit markers in the URL (e.g. _git, .git or //).
// If none are present, we try to apply a historical default repo path length that is derived from
// Github URLs. If there aren't enough segments, we have historically considered the URL invalid.
func parsePathParts(n string, defaultSegmentLength int) (string, string, error) {
repoPath, kustRootPath, success := tryExplicitMarkerSplit(n)
if !success {
repoPath, kustRootPath, success = tryDefaultLengthSplit(n, defaultSegmentLength)
}
i := strings.Index(n, "/")
if i < 1 {
path, gitRef, gitTimeout, gitSubmodules = peelQuery(n)
return
// Validate the result
if !success || len(repoPath) == 0 {
return "", "", fmt.Errorf("failed to parse repo path segment")
}
j := strings.Index(n[i+1:], "/")
if j >= 0 {
j += i + 1
orgRepo = n[:j]
path, gitRef, gitTimeout, gitSubmodules = peelQuery(n[j+1:])
return
if kustRootPathExitsRepo(kustRootPath) {
return "", "", fmt.Errorf("url path exits repo: %s", n)
}
path = ""
orgRepo, gitRef, gitTimeout, gitSubmodules = peelQuery(n)
return host, orgRepo, path, gitRef, gitSubmodules, gitSuff, gitTimeout
return repoPath, strings.TrimPrefix(kustRootPath, pathSeparator), nil
}
func tryExplicitMarkerSplit(n string) (string, string, bool) {
// Look for the _git delimiter, which by convention is expected to be ONE directory above the repo root.
// If found, split on the NEXT path element, which is the repo root.
// Example: https://username@dev.azure.com/org/project/_git/repo/path/to/kustomization/root
if gitRootIdx := strings.Index(n, gitRootDelimiter); gitRootIdx >= 0 {
gitRootPath := n[:gitRootIdx+len(gitRootDelimiter)]
subpathSegments := strings.Split(n[gitRootIdx+len(gitRootDelimiter):], pathSeparator)
return gitRootPath + subpathSegments[0], strings.Join(subpathSegments[1:], pathSeparator), true
// Look for a double-slash in the path, which if present separates the repo root from the kust path.
// It is a convention, not a real path element, so do not preserve it in the returned value.
// Example: https://github.com/org/repo//path/to/kustomozation/root
} else if repoRootIdx := strings.Index(n, "//"); repoRootIdx >= 0 {
return n[:repoRootIdx], n[repoRootIdx+2:], true
// Look for .git in the path, which if present is part of the directory name of the git repo.
// This means we want to grab everything up to and including that suffix
// Example: https://github.com/org/repo.git/path/to/kustomozation/root
} else if gitSuffixIdx := strings.Index(n, gitSuffix); gitSuffixIdx >= 0 {
upToGitSuffix := n[:gitSuffixIdx+len(gitSuffix)]
afterGitSuffix := n[gitSuffixIdx+len(gitSuffix):]
return upToGitSuffix, afterGitSuffix, true
}
return "", "", false
}
func tryDefaultLengthSplit(n string, defaultSegmentLength int) (string, string, bool) {
// If the default is to take all segments, do so.
if defaultSegmentLength == allSegments {
return n, "", true
// If the default is N segments, make sure we have at least that many and take them if so.
// If we have less than N, we have historically considered the URL invalid.
} else if segments := strings.Split(n, pathSeparator); len(segments) >= defaultSegmentLength {
firstNSegments := strings.Join(segments[:defaultSegmentLength], pathSeparator)
rest := strings.Join(segments[defaultSegmentLength:], pathSeparator)
return firstNSegments, rest, true
}
return "", "", false
}
func kustRootPathExitsRepo(kustRootPath string) bool {
cleanedPath := filepath.Clean(strings.TrimPrefix(kustRootPath, string(filepath.Separator)))
pathElements := strings.Split(cleanedPath, string(filepath.Separator))
return len(pathElements) > 0 &&
pathElements[0] == filesys.ParentDir
}
// Clone git submodules by default.
@@ -154,14 +210,12 @@ const defaultSubmodules = true
// Arbitrary, but non-infinite, timeout for running commands.
const defaultTimeout = 27 * time.Second
func peelQuery(arg string) (string, string, time.Duration, bool) {
// Parse the given arg into a URL. In the event of a parse failure, return
// our defaults.
parsed, err := url.Parse(arg)
func parseQuery(query string) (string, time.Duration, bool) {
values, err := url.ParseQuery(query)
// in event of parse failure, return defaults
if err != nil {
return arg, "", defaultTimeout, defaultSubmodules
return "", defaultTimeout, defaultSubmodules
}
values := parsed.Query()
// ref is the desired git ref to target. Can be specified by in a git URL
// with ?ref=<string> or ?version=<string>, although ref takes precedence.
@@ -192,76 +246,142 @@ func peelQuery(arg string) (string, string, time.Duration, bool) {
}
}
return parsed.Path, ref, duration, submodules
return ref, duration, submodules
}
func parseHostSpec(n string) (string, string) {
var host string
// Start accumulating the host part.
for _, p := range []string{
// Order matters here.
"git::", "gh:", "ssh://", "https://", "http://",
"git@", "github.com:", "github.com/"} {
if len(p) < len(n) && strings.ToLower(n[:len(p)]) == p {
n = n[len(p):]
host += p
func extractHost(n string) (string, string, error) {
n = ignoreForcedGitProtocol(n)
scheme, n := extractScheme(n)
username, n := extractUsername(n)
stdGithub := isStandardGithubHost(n)
acceptSCP := acceptSCPStyle(scheme, username, stdGithub)
// Validate the username and scheme before attempting host/path parsing, because if the parsing
// so far has not succeeded, we will not be able to extract the host and path correctly.
if err := validateScheme(scheme, acceptSCP); err != nil {
return "", "", err
}
// Now that we have extracted a valid scheme+username, we can parse host itself.
// The file protocol specifies an absolute path to a local git repo.
// Everything after the scheme (including any 'username' we found) is actually part of that path.
if scheme == fileScheme {
return scheme, username + n, nil
}
var host, rest = n, ""
if sepIndex := findPathSeparator(n, acceptSCP); sepIndex >= 0 {
host, rest = n[:sepIndex+1], n[sepIndex+1:]
}
// Github URLs are strictly normalized in a way that may discard scheme and username components.
if stdGithub {
scheme, username, host = normalizeGithubHostParts(scheme, username)
}
// Host is required, so do not concat the scheme and username if we didn't find one.
if host == "" {
return "", "", errors.Errorf("failed to parse host segment")
}
return scheme + username + host, rest, nil
}
// ignoreForcedGitProtocol strips the "git::" prefix from URLs.
// We used to use go-getter to handle our urls: https://github.com/hashicorp/go-getter.
// The git:: prefix signaled go-getter to use the git protocol to fetch the url's contents.
// We silently strip this prefix to allow these go-getter-style urls to continue to work,
// although the git protocol (which is insecure and unsupported on many platforms, including Github)
// will not actually be used as intended.
func ignoreForcedGitProtocol(n string) string {
n, found := trimPrefixIgnoreCase(n, "git::")
if found {
log.Println("Warning: Forcing the git protocol using the 'git::' URL prefix is not supported. " +
"Kustomize currently strips this invalid prefix, but will stop doing so in a future release. " +
"Please remove the 'git::' prefix from your configuration.")
}
return n
}
// acceptSCPStyle returns true if the scheme and username indicate potential use of an SCP-style URL.
// With this style, the scheme is not explicit and the path is delimited by a colon.
// Strictly speaking the username is optional in SCP-like syntax, but Kustomize has always
// required it for non-Github URLs.
// Example: user@host.xz:path/to/repo.git/
func acceptSCPStyle(scheme, username string, isGithubURL bool) bool {
return scheme == "" && (username != "" || isGithubURL)
}
func validateScheme(scheme string, acceptSCPStyle bool) error {
// see https://git-scm.com/docs/git-fetch#_git_urls for info relevant to these validations
switch scheme {
case "":
// Empty scheme is only ok if it's a Github URL or if it looks like SCP-style syntax
if !acceptSCPStyle {
return fmt.Errorf("failed to parse scheme")
}
case sshScheme, fileScheme, httpsScheme, httpScheme:
// These are all supported schemes
default:
// At time of writing, we should never end up here because we do not parse out
// unsupported schemes to begin with.
return fmt.Errorf("unsupported scheme %q", scheme)
}
return nil
}
const fileScheme = "file://"
const httpScheme = "http://"
const httpsScheme = "https://"
const sshScheme = "ssh://"
func extractScheme(s string) (string, string) {
for _, prefix := range []string{sshScheme, httpsScheme, httpScheme, fileScheme} {
if rest, found := trimPrefixIgnoreCase(s, prefix); found {
return prefix, rest
}
}
if host == "git@" {
i := strings.Index(n, "/")
if i > -1 {
host += n[:i+1]
n = n[i+1:]
} else {
i = strings.Index(n, ":")
if i > -1 {
host += n[:i+1]
n = n[i+1:]
}
}
return host, n
}
return "", s
}
// If host is a http(s) or ssh URL, grab the domain part.
for _, p := range []string{
"ssh://", "https://", "http://"} {
if strings.HasSuffix(host, p) {
i := strings.Index(n, "/")
if i > -1 {
host += n[0 : i+1]
n = n[i+1:]
}
break
func extractUsername(s string) (string, string) {
var userRegexp = regexp.MustCompile(`^([a-zA-Z][a-zA-Z0-9-]*)@`)
if m := userRegexp.FindStringSubmatch(s); m != nil {
username := m[1] + "@"
return username, s[len(username):]
}
return "", s
}
func isStandardGithubHost(s string) bool {
lowerCased := strings.ToLower(s)
return strings.HasPrefix(lowerCased, "github.com/") ||
strings.HasPrefix(lowerCased, "github.com:")
}
// trimPrefixIgnoreCase returns the rest of s and true if prefix, ignoring case, prefixes s.
// Otherwise, trimPrefixIgnoreCase returns s and false.
func trimPrefixIgnoreCase(s, prefix string) (string, bool) {
if len(prefix) <= len(s) && strings.ToLower(s[:len(prefix)]) == prefix {
return s[len(prefix):], true
}
return s, false
}
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 sepIndex == -1 || (colonIndex > 0 && colonIndex < sepIndex) {
sepIndex = colonIndex
}
}
return normalizeGitHostSpec(host), n
return sepIndex
}
func normalizeGitHostSpec(host string) string {
s := strings.ToLower(host)
if strings.Contains(s, "github.com") {
if strings.Contains(s, "git@") || strings.Contains(s, "ssh:") {
host = "git@github.com:"
} else {
host = "https://github.com/"
}
func normalizeGithubHostParts(scheme, username string) (string, string, string) {
if strings.HasPrefix(scheme, sshScheme) || username != "" {
return "", username, "github.com:"
}
if strings.HasPrefix(s, "git::") {
host = strings.TrimPrefix(s, "git::")
}
return host
}
// The format of Azure repo URL is documented
// https://docs.microsoft.com/en-us/azure/devops/repos/git/clone?view=vsts&tabs=visual-studio#clone_url
func isAzureHost(host string) bool {
return strings.Contains(host, "dev.azure.com") ||
strings.Contains(host, "visualstudio.com")
}
// The format of AWS repo URL is documented
// https://docs.aws.amazon.com/codecommit/latest/userguide/regions.html
func isAWSHost(host string) bool {
return strings.Contains(host, "amazonaws.com")
return httpsScheme, "", "github.com/"
}

File diff suppressed because it is too large Load Diff

View File

@@ -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)

View File

@@ -5,9 +5,6 @@ package builtinpluginconsts
const commonLabelFieldSpecs = `
commonLabels:
- path: metadata/labels
create: true
- path: spec/selector
create: true
version: v1
@@ -17,20 +14,10 @@ commonLabels:
create: true
version: v1
kind: ReplicationController
- path: spec/template/metadata/labels
create: true
version: v1
kind: ReplicationController
- path: spec/selector/matchLabels
create: true
kind: Deployment
- path: spec/template/metadata/labels
create: true
kind: Deployment
- path: spec/template/spec/affinity/podAffinity/preferredDuringSchedulingIgnoredDuringExecution/podAffinityTerm/labelSelector/matchLabels
create: false
group: apps
@@ -60,28 +47,15 @@ commonLabels:
create: true
kind: ReplicaSet
- path: spec/template/metadata/labels
create: true
kind: ReplicaSet
- path: spec/selector/matchLabels
create: true
kind: DaemonSet
- path: spec/template/metadata/labels
create: true
kind: DaemonSet
- path: spec/selector/matchLabels
create: true
group: apps
kind: StatefulSet
- path: spec/template/metadata/labels
create: true
group: apps
kind: StatefulSet
- path: spec/template/spec/affinity/podAffinity/preferredDuringSchedulingIgnoredDuringExecution/podAffinityTerm/labelSelector/matchLabels
create: false
group: apps
@@ -107,36 +81,16 @@ commonLabels:
group: apps
kind: StatefulSet
- path: spec/volumeClaimTemplates[]/metadata/labels
create: true
group: apps
kind: StatefulSet
- path: spec/selector/matchLabels
create: false
group: batch
kind: Job
- path: spec/template/metadata/labels
create: true
group: batch
kind: Job
- path: spec/jobTemplate/spec/selector/matchLabels
create: false
group: batch
kind: CronJob
- path: spec/jobTemplate/metadata/labels
create: true
group: batch
kind: CronJob
- path: spec/jobTemplate/spec/template/metadata/labels
create: true
group: batch
kind: CronJob
- path: spec/selector/matchLabels
create: false
group: policy
@@ -156,4 +110,4 @@ commonLabels:
create: false
group: networking.k8s.io
kind: NetworkPolicy
`
` + metadataLabelsFieldSpecs

View File

@@ -13,6 +13,7 @@ func GetDefaultFieldSpecs() []byte {
[]byte(namePrefixFieldSpecs),
[]byte(nameSuffixFieldSpecs),
[]byte(commonLabelFieldSpecs),
[]byte(templateLabelFieldSpecs),
[]byte(commonAnnotationFieldSpecs),
[]byte(namespaceFieldSpecs),
[]byte(varReferenceFieldSpecs),
@@ -30,6 +31,7 @@ func GetDefaultFieldSpecsAsMap() map[string]string {
result["nameprefix"] = namePrefixFieldSpecs
result["namesuffix"] = nameSuffixFieldSpecs
result["commonlabels"] = commonLabelFieldSpecs
result["templatelabels"] = templateLabelFieldSpecs
result["commonannotations"] = commonAnnotationFieldSpecs
result["namespace"] = namespaceFieldSpecs
result["varreference"] = varReferenceFieldSpecs

View File

@@ -0,0 +1,51 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package builtinpluginconsts
const metadataLabelsFieldSpecs = `
- path: metadata/labels
create: true
- path: spec/template/metadata/labels
create: true
version: v1
kind: ReplicationController
- path: spec/template/metadata/labels
create: true
kind: Deployment
- path: spec/template/metadata/labels
create: true
kind: ReplicaSet
- path: spec/template/metadata/labels
create: true
kind: DaemonSet
- path: spec/template/metadata/labels
create: true
group: apps
kind: StatefulSet
- path: spec/volumeClaimTemplates[]/metadata/labels
create: true
group: apps
kind: StatefulSet
- path: spec/template/metadata/labels
create: true
group: batch
kind: Job
- path: spec/jobTemplate/metadata/labels
create: true
group: batch
kind: CronJob
- path: spec/jobTemplate/spec/template/metadata/labels
create: true
group: batch
kind: CronJob
`

View File

@@ -6,15 +6,9 @@ package builtinpluginconsts
const (
namespaceFieldSpecs = `
namespace:
- path: metadata/namespace
create: true
- path: metadata/name
kind: Namespace
create: true
- path: subjects
kind: RoleBinding
- path: subjects
kind: ClusterRoleBinding
- path: spec/service/namespace
group: apiregistration.k8s.io
kind: APIService

View File

@@ -0,0 +1,8 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package builtinpluginconsts
const templateLabelFieldSpecs = `
templateLabels:
` + metadataLabelsFieldSpecs

View File

@@ -0,0 +1,11 @@
// Copyright 2022 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package loader
import "sigs.k8s.io/kustomize/kyaml/errors"
var (
ErrHTTP = errors.Errorf("HTTP Error")
ErrRtNotDir = errors.Errorf("must build at directory")
)

View File

@@ -4,9 +4,8 @@
package loader
import (
"errors"
"fmt"
"io/ioutil"
"io"
"log"
"net/http"
"net/url"
@@ -15,10 +14,18 @@ import (
"sigs.k8s.io/kustomize/api/ifc"
"sigs.k8s.io/kustomize/api/internal/git"
"sigs.k8s.io/kustomize/kyaml/errors"
"sigs.k8s.io/kustomize/kyaml/filesys"
)
// fileLoader is a kustomization's interface to files.
// IsRemoteFile returns whether path has a url scheme that kustomize allows for
// remote files. See https://github.com/kubernetes-sigs/kustomize/blob/master/examples/remoteBuild.md
func IsRemoteFile(path string) bool {
u, err := url.Parse(path)
return err == nil && (u.Scheme == "http" || u.Scheme == "https")
}
// 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_.
@@ -31,49 +38,48 @@ import (
//
// * 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
@@ -100,30 +106,25 @@ 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 {
if fl.repoSpec != nil {
return fl.repoSpec.Dir.String()
}
return ""
}
// 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 {
root, err := demandDirectoryRoot(fSys, path)
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)
}
@@ -131,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,
@@ -146,30 +147,11 @@ func newLoaderAtConfirmedDir(
}
}
// Assure that the given path is in fact a directory.
func demandDirectoryRoot(
fSys filesys.FileSystem, path string) (filesys.ConfirmedDir, error) {
if path == "" {
return "", fmt.Errorf(
"loader root cannot be empty")
}
d, f, err := fSys.CleanedAbs(path)
if err != nil {
return "", err
}
if f != "" {
return "", fmt.Errorf(
"'%s' must be a directory so that it can used as a build root",
path)
}
return d, nil
}
// 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, fmt.Errorf("new root cannot be empty")
return nil, errors.Errorf("new root cannot be empty")
}
repoSpec, err := git.NewRepoSpecFromURL(path)
@@ -185,9 +167,9 @@ func (fl *fileLoader) New(path string) (ifc.Loader, error) {
if filepath.IsAbs(path) {
return nil, fmt.Errorf("new root '%s' cannot be absolute", path)
}
root, err := demandDirectoryRoot(fl.fSys, fl.root.Join(path))
root, err := filesys.ConfirmDir(fl.fSys, fl.root.Join(path))
if err != nil {
return nil, err
return nil, errors.WrapPrefixf(err, ErrRtNotDir.Error())
}
if err = fl.errIfGitContainmentViolation(root); err != nil {
return nil, err
@@ -203,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 {
@@ -225,7 +207,14 @@ func newLoaderAtGitClone(
"'%s' refers to file '%s'; expecting directory",
repoSpec.AbsPath(), f)
}
return &fileLoader{
// Path in repo can contain symlinks that exit repo. We can only
// check for this after cloning repo.
if !root.HasPrefix(repoSpec.CloneDir()) {
_ = cleaner()
return nil, fmt.Errorf("%q refers to directory outside of repo %q", repoSpec.AbsPath(),
repoSpec.CloneDir())
}
return &FileLoader{
// Clones never allowed to escape root.
loadRestrictor: RestrictionRootOnly,
root: root,
@@ -237,7 +226,7 @@ func newLoaderAtGitClone(
}, nil
}
func (fl *fileLoader) errIfGitContainmentViolation(
func (fl *FileLoader) errIfGitContainmentViolation(
base filesys.ConfirmedDir) error {
containingRepo := fl.containingRepo()
if containingRepo == nil {
@@ -255,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
}
@@ -267,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(
@@ -284,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()) {
@@ -301,31 +290,9 @@ 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) {
if u, err := url.Parse(path); err == nil && (u.Scheme == "http" || u.Scheme == "https") {
var hc *http.Client
if fl.http != nil {
hc = fl.http
} else {
hc = &http.Client{}
}
resp, err := hc.Get(path)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode < 200 || resp.StatusCode > 299 {
_, err := git.NewRepoSpecFromURL(path)
if err == nil {
return nil, errors.New("URL is a git repository")
}
return nil, fmt.Errorf("%w: status code %d (%s)", ErrorHTTP, resp.StatusCode, http.StatusText(resp.StatusCode))
}
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
return body, nil
func (fl *FileLoader) Load(path string) ([]byte, error) {
if IsRemoteFile(path) {
return fl.httpClientGetContent(path)
}
if !filepath.IsAbs(path) {
path = fl.root.Join(path)
@@ -337,7 +304,31 @@ func (fl *fileLoader) Load(path string) ([]byte, error) {
return fl.fSys.ReadFile(path)
}
func (fl *FileLoader) httpClientGetContent(path string) ([]byte, error) {
var hc *http.Client
if fl.http != nil {
hc = fl.http
} else {
hc = &http.Client{}
}
resp, err := hc.Get(path)
if err != nil {
return nil, errors.Wrap(err)
}
defer resp.Body.Close()
// response unsuccessful
if resp.StatusCode < 200 || resp.StatusCode > 299 {
_, err = git.NewRepoSpecFromURL(path)
if err == nil {
return nil, errors.Errorf("URL is a git repository")
}
return nil, fmt.Errorf("%w: status code %d (%s)", ErrHTTP, resp.StatusCode, http.StatusText(resp.StatusCode))
}
content, err := io.ReadAll(resp.Body)
return content, errors.Wrap(err)
}
// Cleanup runs the cleaner.
func (fl *fileLoader) Cleanup() error {
func (fl *FileLoader) Cleanup() error {
return fl.cleaner()
}

View File

@@ -5,7 +5,8 @@ package loader
import (
"bytes"
"io/ioutil"
"fmt"
"io"
"net/http"
"os"
"path"
@@ -14,12 +15,52 @@ import (
"strings"
"testing"
"github.com/stretchr/testify/require"
"sigs.k8s.io/kustomize/api/ifc"
"sigs.k8s.io/kustomize/api/internal/git"
"sigs.k8s.io/kustomize/api/konfig"
"sigs.k8s.io/kustomize/kyaml/filesys"
)
func TestIsRemoteFile(t *testing.T) {
cases := map[string]struct {
url string
valid bool
}{
"https file": {
"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,
},
"no scheme": {
"github.com/kubernetes-sigs/kustomize//examples/helloWorld/",
false,
},
"ssh": {
"ssh://git@github.com/kubernetes-sigs/kustomize.git",
false,
},
"local": {
"pod.yaml",
false,
},
}
for name, test := range cases {
test := test
t.Run(name, func(t *testing.T) {
require.Equal(t, test.valid, IsRemoteFile(test.url))
})
}
}
type testData struct {
path string
expectedContent string
@@ -52,129 +93,105 @@ 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) {
require := require.New(t)
l1 := makeLoader()
if "/" != l1.Root() {
t.Fatalf("incorrect root: '%s'\n", l1.Root())
}
repo := l1.Repo()
require.Empty(repo)
require.Equal("/", l1.Root())
for _, x := range testCases {
b, err := l1.Load(x.path)
if err != nil {
t.Fatalf("unexpected load error: %v", err)
}
require.NoError(err)
if !reflect.DeepEqual([]byte(x.expectedContent), b) {
t.Fatalf("in load expected %s, but got %s", x.expectedContent, b)
}
}
l2, err := l1.New("foo/project")
if err != nil {
t.Fatalf("unexpected err: %v\n", err)
}
if "/foo/project" != l2.Root() {
t.Fatalf("incorrect root: %s\n", l2.Root())
}
require.NoError(err)
repo = l2.Repo()
require.Empty(repo)
require.Equal("/foo/project", l2.Root())
for _, x := range testCases {
b, err := l2.Load(strings.TrimPrefix(x.path, "foo/project/"))
if err != nil {
t.Fatalf("unexpected load error %v", err)
}
require.NoError(err)
if !reflect.DeepEqual([]byte(x.expectedContent), b) {
t.Fatalf("in load expected %s, but got %s", x.expectedContent, b)
}
}
l2, err = l1.New("foo/project/") // Assure trailing slash stripped
if err != nil {
t.Fatalf("unexpected err: %v\n", err)
}
if "/foo/project" != l2.Root() {
t.Fatalf("incorrect root: %s\n", l2.Root())
}
require.NoError(err)
require.Equal("/foo/project", l2.Root())
}
func TestLoaderNewSubDir(t *testing.T) {
require := require.New(t)
l1, err := makeLoader().New("foo/project")
if err != nil {
t.Fatalf("unexpected err: %v\n", err)
}
require.NoError(err)
l2, err := l1.New("subdir1")
if err != nil {
t.Fatalf("unexpected err: %v\n", err)
}
if "/foo/project/subdir1" != l2.Root() {
t.Fatalf("incorrect root: %s\n", l2.Root())
}
require.NoError(err)
require.Equal("/foo/project/subdir1", l2.Root())
x := testCases[1]
b, err := l2.Load("fileB.yaml")
if err != nil {
t.Fatalf("unexpected load error %v", err)
}
require.NoError(err)
if !reflect.DeepEqual([]byte(x.expectedContent), b) {
t.Fatalf("in load expected %s, but got %s", x.expectedContent, b)
}
}
func TestLoaderBadRelative(t *testing.T) {
require := require.New(t)
l1, err := makeLoader().New("foo/project/subdir1")
if err != nil {
t.Fatalf("unexpected err: %v\n", err)
}
if "/foo/project/subdir1" != l1.Root() {
t.Fatalf("incorrect root: %s\n", l1.Root())
}
require.NoError(err)
require.Equal("/foo/project/subdir1", l1.Root())
// Cannot cd into a file.
l2, err := l1.New("fileB.yaml")
if err == nil {
t.Fatalf("expected err, but got root %s", l2.Root())
}
require.Error(err)
// It's not okay to stay at the same place.
l2, err = l1.New(filesys.SelfDir)
if err == nil {
t.Fatalf("expected err, but got root %s", l2.Root())
}
require.Error(err)
// It's not okay to go up and back down into same place.
l2, err = l1.New("../subdir1")
if err == nil {
t.Fatalf("expected err, but got root %s", l2.Root())
}
require.Error(err)
// It's not okay to go up via a relative path.
l2, err = l1.New("..")
if err == nil {
t.Fatalf("expected err, but got root %s", l2.Root())
}
require.Error(err)
// It's not okay to go up via an absolute path.
l2, err = l1.New("/foo/project")
if err == nil {
t.Fatalf("expected err, but got root %s", l2.Root())
}
require.Error(err)
// It's not okay to go to the root.
l2, err = l1.New("/")
if err == nil {
t.Fatalf("expected err, but got root %s", l2.Root())
}
require.Error(err)
// It's okay to go up and down to a sibling.
l2, err = l1.New("../subdir2")
if err != nil {
t.Fatalf("unexpected new error %v", err)
}
if "/foo/project/subdir2" != l2.Root() {
t.Fatalf("incorrect root: %s\n", l2.Root())
}
require.NoError(err)
require.Equal("/foo/project/subdir2", l2.Root())
x := testCases[2]
b, err := l2.Load("fileC.yaml")
if err != nil {
t.Fatalf("unexpected load error %v", err)
}
require.NoError(err)
if !reflect.DeepEqual([]byte(x.expectedContent), b) {
t.Fatalf("in load expected %s, but got %s", x.expectedContent, b)
}
@@ -182,21 +199,55 @@ func TestLoaderBadRelative(t *testing.T) {
// It's not OK to go over to a previously visited directory.
// Must disallow going back and forth in a cycle.
l1, err = l2.New("../subdir1")
if err == nil {
t.Fatalf("expected err, but got root %s", l1.Root())
}
require.Error(err)
}
func TestLoaderMisc(t *testing.T) {
l := makeLoader()
_, err := l.New("")
if err == nil {
t.Fatalf("Expected error for empty root location not returned")
}
_, err = l.New("https://google.com/project")
if err == nil {
t.Fatalf("Expected error")
}
func TestNewEmptyLoader(t *testing.T) {
_, err := makeLoader().New("")
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 (
@@ -206,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(
@@ -239,74 +290,53 @@ func commonSetupForLoaderRestrictionTest(t *testing.T) (string, filesys.FileSyst
func doSanityChecksAndDropIntoBase(
t *testing.T, l ifc.Loader) ifc.Loader {
t.Helper()
require := require.New(t)
data, err := l.Load(path.Join("base", "okayData"))
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if string(data) != contentOk {
t.Fatalf("unexpected content: %v", data)
}
require.NoError(err)
require.Equal(contentOk, string(data))
data, err = l.Load("exteriorData")
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if string(data) != contentExteriorData {
t.Fatalf("unexpected content: %v", data)
}
require.NoError(err)
require.Equal(contentExteriorData, string(data))
// Drop in.
l, err = l.New("base")
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
require.NoError(err)
// Reading okayData works.
data, err = l.Load("okayData")
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if string(data) != contentOk {
t.Fatalf("unexpected content: %v", data)
}
require.NoError(err)
require.Equal(contentOk, string(data))
// Reading local symlink to okayData works.
data, err = l.Load("symLinkToOkayData")
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if string(data) != contentOk {
t.Fatalf("unexpected content: %v", data)
}
require.NoError(err)
require.Equal(contentOk, string(data))
return l
}
func TestRestrictionRootOnlyInRealLoader(t *testing.T) {
require := require.New(t)
dir, fSys := commonSetupForLoaderRestrictionTest(t)
var l ifc.Loader
l = newLoaderOrDie(RestrictionRootOnly, fSys, dir)
l = NewLoaderOrDie(RestrictionRootOnly, fSys, dir)
l = doSanityChecksAndDropIntoBase(t, l)
// Reading symlink to exteriorData fails.
_, err := l.Load("symLinkToExteriorData")
if err == nil {
t.Fatalf("expected error")
}
if !strings.Contains(err.Error(), "is not in or below") {
t.Fatalf("unexpected err: %v", err)
}
require.Error(err)
require.Contains(err.Error(), "is not in or below")
// Attempt to read "up" fails, though earlier we were
// able to read this file when root was "..".
_, err = l.Load("../exteriorData")
if err == nil {
t.Fatalf("expected error")
}
if !strings.Contains(err.Error(), "is not in or below") {
t.Fatalf("unexpected err: %v", err)
}
require.Error(err)
require.Contains(err.Error(), "is not in or below")
}
func TestRestrictionNoneInRealLoader(t *testing.T) {
@@ -314,21 +344,17 @@ func TestRestrictionNoneInRealLoader(t *testing.T) {
var l ifc.Loader
l = newLoaderOrDie(RestrictionNone, fSys, dir)
l = NewLoaderOrDie(RestrictionNone, fSys, dir)
l = doSanityChecksAndDropIntoBase(t, l)
// Reading symlink to exteriorData works.
_, err := l.Load("symLinkToExteriorData")
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
require.NoError(t, err)
// Attempt to read "up" works.
_, err = l.Load("../exteriorData")
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
require.NoError(t, err)
}
func splitOnNthSlash(v string, n int) (string, string) {
@@ -358,6 +384,8 @@ func TestSplit(t *testing.T) {
}
func TestNewLoaderAtGitClone(t *testing.T) {
require := require.New(t)
rootURL := "github.com/someOrg/someRepo"
pathInRepo := "foo/base"
url := rootURL + "/" + pathInRepo
@@ -373,40 +401,36 @@ whatever
`))
repoSpec, err := git.NewRepoSpecFromURL(url)
if err != nil {
t.Fatalf("unexpected err: %v\n", err)
}
require.NoError(err)
l, err := newLoaderAtGitClone(
repoSpec, fSys, nil,
git.DoNothingCloner(filesys.ConfirmedDir(coRoot)))
if err != nil {
t.Fatalf("unexpected err: %v\n", err)
}
if coRoot+"/"+pathInRepo != l.Root() {
t.Fatalf("expected root '%s', got '%s'\n",
coRoot+"/"+pathInRepo, l.Root())
}
if _, err = l.New(url); err == nil {
t.Fatalf("expected cycle error 1")
}
if _, err = l.New(rootURL + "/" + "foo"); err == nil {
t.Fatalf("expected cycle error 2")
}
require.NoError(err)
repo := l.Repo()
require.Equal(coRoot, repo)
require.Equal(coRoot+"/"+pathInRepo, l.Root())
_, err = l.New(url)
require.Error(err)
_, err = l.New(rootURL + "/" + "foo")
require.Error(err)
pathInRepo = "foo/overlay"
fSys.MkdirAll(coRoot + "/" + pathInRepo)
url = rootURL + "/" + pathInRepo
l2, err := l.New(url)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if coRoot+"/"+pathInRepo != l2.Root() {
t.Fatalf("expected root '%s', got '%s'\n",
coRoot+"/"+pathInRepo, l2.Root())
}
require.NoError(err)
repo = l2.Repo()
require.Equal(coRoot, repo)
require.Equal(coRoot+"/"+pathInRepo, l2.Root())
}
func TestLoaderDisallowsLocalBaseFromRemoteOverlay(t *testing.T) {
require := require.New(t)
// Define an overlay-base structure in the file system.
topDir := "/whatever"
cloneRoot := topDir + "/someClone"
@@ -419,25 +443,17 @@ 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")
if l1.Root() != cloneRoot+"/foo/overlay" {
t.Fatalf("unexpected root %s", l1.Root())
}
require.Equal(cloneRoot+"/foo/overlay", l1.Root())
l2, err := l1.New("../base")
if err != nil {
t.Fatalf("unexpected err: %v\n", err)
}
if l2.Root() != cloneRoot+"/foo/base" {
t.Fatalf("unexpected root %s", l2.Root())
}
require.NoError(nil)
require.Equal(cloneRoot+"/foo/base", l2.Root())
l3, err := l2.New("../../../highBase")
if err != nil {
t.Fatalf("unexpected err: %v\n", err)
}
if l3.Root() != topDir+"/highBase" {
t.Fatalf("unexpected root %s", l3.Root())
}
require.NoError(err)
require.Equal(topDir+"/highBase", l3.Root())
// Establish that a Kustomization found in cloned
// repo can reach (non-remote) bases inside the clone
@@ -452,125 +468,113 @@ func TestLoaderDisallowsLocalBaseFromRemoteOverlay(t *testing.T) {
// for local K's.
repoSpec, err := git.NewRepoSpecFromURL(
"github.com/someOrg/someRepo/foo/overlay")
if err != nil {
t.Fatalf("unexpected err: %v\n", err)
}
require.NoError(err)
l1, err = newLoaderAtGitClone(
repoSpec, fSys, nil,
git.DoNothingCloner(filesys.ConfirmedDir(cloneRoot)))
if err != nil {
t.Fatalf("unexpected err: %v\n", err)
}
if l1.Root() != cloneRoot+"/foo/overlay" {
t.Fatalf("unexpected root %s", l1.Root())
}
require.NoError(err)
require.Equal(cloneRoot+"/foo/overlay", l1.Root())
// This is okay.
l2, err = l1.New("../base")
if err != nil {
t.Fatalf("unexpected err: %v\n", err)
}
if l2.Root() != cloneRoot+"/foo/base" {
t.Fatalf("unexpected root %s", l2.Root())
}
require.NoError(err)
repo := l2.Repo()
require.Empty(repo)
require.Equal(cloneRoot+"/foo/base", l2.Root())
// This is not okay.
_, err = l2.New("../../../highBase")
if err == nil {
t.Fatalf("expected err")
}
if !strings.Contains(err.Error(),
"base '/whatever/highBase' is outside '/whatever/someClone'") {
t.Fatalf("unexpected err: %v", err)
}
require.Error(err)
require.Contains(err.Error(),
"base '/whatever/highBase' is outside '/whatever/someClone'")
}
func TestLoaderDisallowsRemoteBaseExitRepo(t *testing.T) {
fSys, dir := setupOnDisk(t)
repo := dir.Join("repo")
require.NoError(t, fSys.Mkdir(repo))
base := filepath.Join(repo, "base")
require.NoError(t, os.Symlink(dir.String(), base))
repoSpec, err := git.NewRepoSpecFromURL("https://github.com/org/repo/base")
require.NoError(t, err)
_, err = newLoaderAtGitClone(repoSpec, fSys, nil, git.DoNothingCloner(filesys.ConfirmedDir(repo)))
require.Error(t, err)
require.Contains(t, err.Error(), fmt.Sprintf("%q refers to directory outside of repo %q", base, repo))
}
func TestLocalLoaderReferencingGitBase(t *testing.T) {
require := require.New(t)
topDir := "/whatever"
cloneRoot := topDir + "/someClone"
fSys := filesys.MakeFsInMemory()
fSys.MkdirAll(topDir)
fSys.MkdirAll(cloneRoot + "/foo/base")
root, err := demandDirectoryRoot(fSys, topDir)
if err != nil {
t.Fatalf("unexpected err: %v\n", err)
}
l1 := newLoaderAtConfirmedDir(
RestrictionRootOnly, root, fSys, nil,
RestrictionRootOnly, filesys.ConfirmedDir(topDir), fSys, nil,
git.DoNothingCloner(filesys.ConfirmedDir(cloneRoot)))
if l1.Root() != topDir {
t.Fatalf("unexpected root %s", l1.Root())
}
require.Equal(topDir, l1.Root())
l2, err := l1.New("github.com/someOrg/someRepo/foo/base")
if err != nil {
t.Fatalf("unexpected err: %v\n", err)
}
if l2.Root() != cloneRoot+"/foo/base" {
t.Fatalf("unexpected root %s", l2.Root())
}
require.NoError(err)
repo := l2.Repo()
require.Equal(cloneRoot, repo)
require.Equal(cloneRoot+"/foo/base", l2.Root())
}
func TestRepoDirectCycleDetection(t *testing.T) {
require := require.New(t)
topDir := "/cycles"
cloneRoot := topDir + "/someClone"
fSys := filesys.MakeFsInMemory()
fSys.MkdirAll(topDir)
fSys.MkdirAll(cloneRoot)
root, err := demandDirectoryRoot(fSys, topDir)
if err != nil {
t.Fatalf("unexpected err: %v\n", err)
}
l1 := newLoaderAtConfirmedDir(
RestrictionRootOnly, root, fSys, nil,
RestrictionRootOnly, filesys.ConfirmedDir(topDir), fSys, nil,
git.DoNothingCloner(filesys.ConfirmedDir(cloneRoot)))
p1 := "github.com/someOrg/someRepo/foo"
rs1, err := git.NewRepoSpecFromURL(p1)
if err != nil {
t.Fatalf("unexpected err: %v", err)
}
require.NoError(err)
l1.repoSpec = rs1
_, err = l1.New(p1)
if err == nil {
t.Fatalf("expected error")
}
if !strings.Contains(err.Error(), "cycle detected") {
t.Fatalf("unexpected err: %v", err)
}
require.Error(err)
require.Contains(err.Error(), "cycle detected")
}
func TestRepoIndirectCycleDetection(t *testing.T) {
require := require.New(t)
topDir := "/cycles"
cloneRoot := topDir + "/someClone"
fSys := filesys.MakeFsInMemory()
fSys.MkdirAll(topDir)
fSys.MkdirAll(cloneRoot)
root, err := demandDirectoryRoot(fSys, topDir)
if err != nil {
t.Fatalf("unexpected err: %v", err)
}
l0 := newLoaderAtConfirmedDir(
RestrictionRootOnly, root, fSys, nil,
RestrictionRootOnly, filesys.ConfirmedDir(topDir), fSys, nil,
git.DoNothingCloner(filesys.ConfirmedDir(cloneRoot)))
p1 := "github.com/someOrg/someRepo1"
p2 := "github.com/someOrg/someRepo2"
l1, err := l0.New(p1)
if err != nil {
t.Fatalf("unexpected err: %v", err)
}
require.NoError(err)
l2, err := l1.New(p2)
if err != nil {
t.Fatalf("unexpected err: %v", err)
}
require.NoError(err)
_, err = l2.New(p1)
if err == nil {
t.Fatalf("expected error")
}
if !strings.Contains(err.Error(), "cycle detected") {
t.Fatalf("unexpected err: %v", err)
}
require.Error(err)
require.Contains(err.Error(), "cycle detected")
}
// Inspired by https://hassansin.github.io/Unit-Testing-http-client-in-Go
@@ -588,6 +592,8 @@ func makeFakeHTTPClient(fn fakeRoundTripper) *http.Client {
// TestLoaderHTTP test http file loader
func TestLoaderHTTP(t *testing.T) {
require := require.New(t)
var testCasesFile = []testData{
{
path: "http/file.yaml",
@@ -595,15 +601,13 @@ func TestLoaderHTTP(t *testing.T) {
},
}
l1 := NewFileLoaderAtRoot(MakeFakeFs(testCasesFile))
if "/" != l1.Root() {
t.Fatalf("incorrect root: '%s'\n", l1.Root())
}
l1 := NewLoaderOrDie(
RestrictionRootOnly, MakeFakeFs(testCasesFile), filesys.Separator)
require.Equal("/", l1.Root())
for _, x := range testCasesFile {
b, err := l1.Load(x.path)
if err != nil {
t.Fatalf("unexpected load error: %v", err)
}
require.NoError(err)
if !reflect.DeepEqual([]byte(x.expectedContent), b) {
t.Fatalf("in load expected %s, but got %s", x.expectedContent, b)
}
@@ -623,21 +627,17 @@ func TestLoaderHTTP(t *testing.T) {
for _, x := range testCasesHTTP {
hc := makeFakeHTTPClient(func(req *http.Request) *http.Response {
u := req.URL.String()
if x.path != u {
t.Fatalf("expected URL %s, but got %s", x.path, u)
}
require.Equal(x.path, u)
return &http.Response{
StatusCode: 200,
Body: ioutil.NopCloser(bytes.NewBufferString(x.expectedContent)),
Body: io.NopCloser(bytes.NewBufferString(x.expectedContent)),
Header: make(http.Header),
}
})
l2 := l1
l2.http = hc
b, err := l2.Load(x.path)
if err != nil {
t.Fatalf("unexpected load error: %v", err)
}
require.NoError(err)
if !reflect.DeepEqual([]byte(x.expectedContent), b) {
t.Fatalf("in load expected %s, but got %s", x.expectedContent, b)
}
@@ -657,8 +657,22 @@ func TestLoaderHTTP(t *testing.T) {
l2 := l1
l2.http = hc
_, err := l2.Load(x.path)
if err == nil {
t.Fatalf("expect error but get %v", err)
}
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
}

View File

@@ -7,6 +7,7 @@ package loader
import (
"sigs.k8s.io/kustomize/api/ifc"
"sigs.k8s.io/kustomize/api/internal/git"
"sigs.k8s.io/kustomize/kyaml/errors"
"sigs.k8s.io/kustomize/kyaml/filesys"
)
@@ -25,9 +26,9 @@ func NewLoader(
return newLoaderAtGitClone(
repoSpec, fSys, nil, git.ClonerUsingGitExec)
}
root, err := demandDirectoryRoot(fSys, target)
root, err := filesys.ConfirmDir(fSys, target)
if err != nil {
return nil, err
return nil, errors.WrapPrefixf(err, ErrRtNotDir.Error())
}
return newLoaderAtConfirmedDir(
lr, root, fSys, nil, git.ClonerUsingGitExec), nil

View File

@@ -0,0 +1,152 @@
// Copyright 2022 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package localizer
import (
"sigs.k8s.io/kustomize/api/filters/fieldspec"
"sigs.k8s.io/kustomize/api/filters/filtersutil"
"sigs.k8s.io/kustomize/api/filters/fsslice"
"sigs.k8s.io/kustomize/api/internal/plugins/builtinhelpers"
"sigs.k8s.io/kustomize/api/konfig"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/errors"
"sigs.k8s.io/kustomize/kyaml/kio"
"sigs.k8s.io/kustomize/kyaml/resid"
"sigs.k8s.io/kustomize/kyaml/yaml"
)
// localizeBuiltinPlugins localizes built-in plugins with file paths.
// Note that this excludes helm, which needs a repo.
type localizeBuiltinPlugins struct {
lc *localizer
// locPathFn is used by localizeNode to set the localized path on the plugin.
locPathFn func(string) (string, error)
}
var _ kio.Filter = &localizeBuiltinPlugins{}
// Filter localizes the built-in plugins with file paths.
func (lbp *localizeBuiltinPlugins) Filter(plugins []*yaml.RNode) ([]*yaml.RNode, error) {
for _, singlePlugin := range plugins {
err := singlePlugin.PipeE(fsslice.Filter{
FsSlice: types.FsSlice{
types.FieldSpec{
Gvk: resid.Gvk{Version: konfig.BuiltinPluginApiVersion, Kind: builtinhelpers.ConfigMapGenerator.String()},
Path: "env",
},
types.FieldSpec{
Gvk: resid.Gvk{Version: konfig.BuiltinPluginApiVersion, Kind: builtinhelpers.ConfigMapGenerator.String()},
Path: "envs",
},
types.FieldSpec{
Gvk: resid.Gvk{Version: konfig.BuiltinPluginApiVersion, Kind: builtinhelpers.SecretGenerator.String()},
Path: "env",
},
types.FieldSpec{
Gvk: resid.Gvk{Version: konfig.BuiltinPluginApiVersion, Kind: builtinhelpers.SecretGenerator.String()},
Path: "envs",
},
types.FieldSpec{
Gvk: resid.Gvk{Version: konfig.BuiltinPluginApiVersion, Kind: builtinhelpers.HelmChartInflationGenerator.String()},
Path: "valuesFile",
},
types.FieldSpec{
Gvk: resid.Gvk{Version: konfig.BuiltinPluginApiVersion, Kind: builtinhelpers.HelmChartInflationGenerator.String()},
Path: "additionalValuesFiles",
},
types.FieldSpec{
Gvk: resid.Gvk{Version: konfig.BuiltinPluginApiVersion, Kind: builtinhelpers.PatchTransformer.String()},
Path: "path",
},
types.FieldSpec{
Gvk: resid.Gvk{Version: konfig.BuiltinPluginApiVersion, Kind: builtinhelpers.PatchJson6902Transformer.String()},
Path: "path",
},
types.FieldSpec{
Gvk: resid.Gvk{Version: konfig.BuiltinPluginApiVersion, Kind: builtinhelpers.ReplacementTransformer.String()},
Path: "replacements/path",
},
},
SetValue: func(node *yaml.RNode) error {
lbp.locPathFn = lbp.lc.localizeFile
return lbp.localizeAll(node)
},
},
fsslice.Filter{
FsSlice: types.FsSlice{
types.FieldSpec{
Gvk: resid.Gvk{Version: konfig.BuiltinPluginApiVersion, Kind: builtinhelpers.ConfigMapGenerator.String()},
Path: "files",
},
types.FieldSpec{
Gvk: resid.Gvk{Version: konfig.BuiltinPluginApiVersion, Kind: builtinhelpers.SecretGenerator.String()},
Path: "files",
},
},
SetValue: func(node *yaml.RNode) error {
lbp.locPathFn = lbp.lc.localizeFileSource
return lbp.localizeAll(node)
},
},
yaml.FilterFunc(func(node *yaml.RNode) (*yaml.RNode, error) {
isHelm := node.GetApiVersion() == konfig.BuiltinPluginApiVersion &&
node.GetKind() == builtinhelpers.HelmChartInflationGenerator.String()
if !isHelm {
return node, nil
}
home, err := node.Pipe(yaml.Lookup("chartHome"))
if err != nil {
return nil, errors.Wrap(err)
}
if home == nil {
_, err = lbp.lc.copyChartHomeEntry("")
} else {
lbp.locPathFn = lbp.lc.copyChartHomeEntry
err = lbp.localizeScalar(home)
}
return node, errors.WrapPrefixf(err, "plugin %s", resid.FromRNode(node))
}),
fieldspec.Filter{
FieldSpec: types.FieldSpec{
Gvk: resid.Gvk{Version: konfig.BuiltinPluginApiVersion, Kind: builtinhelpers.PatchStrategicMergeTransformer.String()},
Path: "paths",
},
SetValue: func(node *yaml.RNode) error {
lbp.locPathFn = lbp.lc.localizeK8sResource
return lbp.localizeAll(node)
},
})
if err != nil {
return nil, errors.Wrap(err)
}
}
return plugins, nil
}
// localizeAll sets each entry in node to its value localized by locPathFn.
// Node is a sequence or scalar value.
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))
case yaml.ScalarNode:
return lbp.localizeScalar(node)
default:
return errors.Errorf("expected sequence or scalar node")
}
}
// localizeScalar sets the scalar node to its value localized by locPathFn.
func (lbp *localizeBuiltinPlugins) localizeScalar(node *yaml.RNode) error {
localizedPath, err := lbp.locPathFn(node.YNode().Value)
if err != nil {
return err
}
return filtersutil.SetScalar(localizedPath)(node)
}

View File

@@ -0,0 +1,7 @@
// Copyright 2022 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
// Package localizer contains utilities for the command kustomize localize, which is
// documented under proposals/localize-command or at
// https://github.com/kubernetes-sigs/kustomize/blob/master/proposals/22-04-localize-command.md
package localizer

View File

@@ -0,0 +1,27 @@
// Copyright 2022 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package localizer
import "fmt"
type ResourceLoadError struct {
InlineError error
FileError error
}
func (rle ResourceLoadError) Error() string {
return fmt.Sprintf(`when parsing as inline received error: %s
when parsing as filepath received error: %s`, rle.InlineError, rle.FileError)
}
type PathLocalizeError struct {
Path string
FileError error
RootError error
}
func (ple PathLocalizeError) Error() string {
return fmt.Sprintf(`could not localize path %q as file: %s; could not localize path %q as directory: %s`,
ple.Path, ple.FileError, ple.Path, ple.RootError)
}

View File

@@ -0,0 +1,613 @@
// Copyright 2022 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package localizer
import (
"io/fs"
"log"
"os"
"path/filepath"
"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/provider"
"sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/types"
"sigs.k8s.io/kustomize/kyaml/errors"
"sigs.k8s.io/kustomize/kyaml/filesys"
"sigs.k8s.io/yaml"
)
// localizer encapsulates all state needed to localize the root at ldr.
type localizer struct {
fSys filesys.FileSystem
// underlying type is Loader
ldr ifc.Loader
// root is at ldr.Root()
root filesys.ConfirmedDir
rFactory *resmap.Factory
// destination directory in newDir that mirrors root
dst string
}
// Run attempts to localize the kustomization root at target with the given localize arguments
// and returns the path to the created newDir.
func Run(target, scope, newDir string, fSys filesys.FileSystem) (string, error) {
ldr, args, err := NewLoader(target, scope, newDir, fSys)
if err != nil {
return "", errors.Wrap(err)
}
defer func() { _ = ldr.Cleanup() }()
toDst, err := filepath.Rel(args.Scope.String(), args.Target.String())
if err != nil {
log.Panicf("cannot find path from %q to child directory %q: %s", args.Scope, args.Target, err)
}
dst := args.NewDir.Join(toDst)
if err = fSys.MkdirAll(dst); err != nil {
return "", errors.WrapPrefixf(err, "unable to create directory in localize destination")
}
err = (&localizer{
fSys: fSys,
ldr: ldr,
root: args.Target,
rFactory: resmap.NewFactory(provider.NewDepProvider().GetResourceFactory()),
dst: dst,
}).localize()
if err != nil {
errCleanup := fSys.RemoveAll(args.NewDir.String())
if errCleanup != nil {
log.Printf("unable to clean localize destination: %s", errCleanup)
}
return "", errors.WrapPrefixf(err, "unable to localize target %q", target)
}
return args.NewDir.String(), nil
}
// localize localizes the root that lc is at
func (lc *localizer) localize() error {
kustomization, kustFileName, err := lc.load()
if err != nil {
return err
}
err = lc.localizeNativeFields(kustomization)
if err != nil {
return err
}
err = lc.localizeBuiltinPlugins(kustomization)
if err != nil {
return err
}
content, err := yaml.Marshal(kustomization)
if err != nil {
return errors.WrapPrefixf(err, "unable to serialize localized kustomization file")
}
if err = lc.fSys.WriteFile(filepath.Join(lc.dst, kustFileName), content); err != nil {
return errors.WrapPrefixf(err, "unable to write localized kustomization file")
}
return nil
}
// load returns the kustomization at lc.root and the file name under which it was found
func (lc *localizer) load() (*types.Kustomization, string, error) {
content, kustFileName, err := target.LoadKustFile(lc.ldr)
if err != nil {
return nil, "", errors.Wrap(err)
}
var kust types.Kustomization
err = (&kust).Unmarshal(content)
if err != nil {
return nil, "", errors.Wrap(err)
}
// Localize intentionally does not replace legacy fields to return a localized kustomization
// with as much resemblance to the original as possible.
// Localize also intentionally does not enforce fields, as localize does not wish to unnecessarily
// repeat the responsibilities of kustomize build.
return &kust, kustFileName, nil
}
// localizeNativeFields localizes paths on kustomize-native fields, like configMapGenerator, that kustomize has a
// built-in understanding of. This excludes helm-related fields, such as `helmGlobals` and `helmCharts`.
func (lc *localizer) localizeNativeFields(kust *types.Kustomization) error {
if path, exists := kust.OpenAPI["path"]; exists {
locPath, err := lc.localizeFile(path)
if err != nil {
return errors.WrapPrefixf(err, "unable to localize openapi path")
}
kust.OpenAPI["path"] = locPath
}
for fieldName, field := range map[string]struct {
paths []string
locFn func(string) (string, error)
}{
"bases": {
// Allow use of deprecated field
//nolint:staticcheck
kust.Bases,
lc.localizeRoot,
},
"components": {
kust.Components,
lc.localizeRoot,
},
"configurations": {
kust.Configurations,
lc.localizeFile,
},
"crds": {
kust.Crds,
lc.localizeFile,
},
"resources": {
kust.Resources,
lc.localizeResource,
},
} {
for i, path := range field.paths {
locPath, err := field.locFn(path)
if err != nil {
return errors.WrapPrefixf(err, "unable to localize %s entry", fieldName)
}
field.paths[i] = locPath
}
}
for i := range kust.ConfigMapGenerator {
if err := lc.localizeGenerator(&kust.ConfigMapGenerator[i].GeneratorArgs); err != nil {
return errors.WrapPrefixf(err, "unable to localize configMapGenerator")
}
}
for i := range kust.SecretGenerator {
if err := lc.localizeGenerator(&kust.SecretGenerator[i].GeneratorArgs); err != nil {
return errors.WrapPrefixf(err, "unable to localize secretGenerator")
}
}
if err := lc.localizeHelmInflationGenerator(kust); err != nil {
return err
}
if err := lc.localizeHelmCharts(kust); err != nil {
return err
}
if err := lc.localizePatches(kust.Patches); err != nil {
return errors.WrapPrefixf(err, "unable to localize patches")
}
//nolint:staticcheck
if err := lc.localizePatches(kust.PatchesJson6902); err != nil {
return errors.WrapPrefixf(err, "unable to localize patchesJson6902")
}
//nolint:staticcheck
for i, patch := range kust.PatchesStrategicMerge {
locPath, err := lc.localizeK8sResource(string(patch))
if err != nil {
return errors.WrapPrefixf(err, "unable to localize patchesStrategicMerge entry")
}
kust.PatchesStrategicMerge[i] = types.PatchStrategicMerge(locPath)
}
for i, replacement := range kust.Replacements {
locPath, err := lc.localizeFile(replacement.Path)
if err != nil {
return errors.WrapPrefixf(err, "unable to localize replacements entry")
}
kust.Replacements[i].Path = locPath
}
return nil
}
// localizeGenerator localizes the file paths on generator.
func (lc *localizer) localizeGenerator(generator *types.GeneratorArgs) error {
locEnvSrc, err := lc.localizeFile(generator.EnvSource)
if err != nil {
return errors.WrapPrefixf(err, "unable to localize generator env file")
}
locEnvs := make([]string, len(generator.EnvSources))
for i, env := range generator.EnvSources {
locEnvs[i], err = lc.localizeFile(env)
if err != nil {
return errors.WrapPrefixf(err, "unable to localize generator envs file")
}
}
locFiles := make([]string, len(generator.FileSources))
for i, file := range generator.FileSources {
locFiles[i], err = lc.localizeFileSource(file)
if err != nil {
return err
}
}
generator.EnvSource = locEnvSrc
generator.EnvSources = locEnvs
generator.FileSources = locFiles
return nil
}
// localizeFileSource returns the localized file source found in configMap and
// secretGenerators.
func (lc *localizer) localizeFileSource(source string) (string, error) {
key, file, err := generators.ParseFileSource(source)
if err != nil {
return "", errors.Wrap(err)
}
locFile, err := lc.localizeFile(file)
if err != nil {
return "", errors.WrapPrefixf(err, "invalid file source %q", source)
}
var locSource string
if source == file {
locSource = locFile
} else {
locSource = key + "=" + locFile
}
return locSource, nil
}
// localizeHelmInflationGenerator localizes helmChartInflationGenerator on kust.
// localizeHelmInflationGenerator localizes values files and copies local chart homes.
func (lc *localizer) localizeHelmInflationGenerator(kust *types.Kustomization) error {
for i, chart := range kust.HelmChartInflationGenerator {
locFile, err := lc.localizeFile(chart.Values)
if err != nil {
return errors.WrapPrefixf(err, "unable to localize helmChartInflationGenerator entry %d values", i)
}
kust.HelmChartInflationGenerator[i].Values = locFile
locDir, err := lc.copyChartHomeEntry(chart.ChartHome)
if err != nil {
return errors.WrapPrefixf(err, "unable to copy helmChartInflationGenerator entry %d", i)
}
kust.HelmChartInflationGenerator[i].ChartHome = locDir
}
return nil
}
// localizeHelmCharts localizes helmCharts and helmGlobals on kust.
// localizeHelmCharts localizes values files and copies a local chart home.
func (lc *localizer) localizeHelmCharts(kust *types.Kustomization) error {
for i, chart := range kust.HelmCharts {
locFile, err := lc.localizeFile(chart.ValuesFile)
if err != nil {
return errors.WrapPrefixf(err, "unable to localize helmCharts entry %d valuesFile", i)
}
kust.HelmCharts[i].ValuesFile = locFile
for j, valuesFile := range chart.AdditionalValuesFiles {
locFile, err = lc.localizeFile(valuesFile)
if err != nil {
return errors.WrapPrefixf(err, "unable to localize helmCharts entry %d additionalValuesFiles", i)
}
kust.HelmCharts[i].AdditionalValuesFiles[j] = locFile
}
}
if kust.HelmGlobals != nil {
locDir, err := lc.copyChartHomeEntry(kust.HelmGlobals.ChartHome)
if err != nil {
return errors.WrapPrefixf(err, "unable to copy helmGlobals")
}
kust.HelmGlobals.ChartHome = locDir
} else if len(kust.HelmCharts) > 0 {
_, err := lc.copyChartHomeEntry("")
if err != nil {
return errors.WrapPrefixf(err, "unable to copy default chart home")
}
}
return nil
}
// localizePatches localizes the file paths on patches if they are non-empty
func (lc *localizer) localizePatches(patches []types.Patch) error {
for i := range patches {
locPath, err := lc.localizeFile(patches[i].Path)
if err != nil {
return err
}
patches[i].Path = locPath
}
return nil
}
// localizeResource localizes resource path, a file or root, and returns the
// localized path
func (lc *localizer) localizeResource(path string) (string, error) {
var locPath string
content, fileErr := lc.ldr.Load(path)
// The following check catches the case where path is a repo root.
// Load on a repo will successfully return its README in HTML.
// Because HTML does not follow resource formatting, we then correctly try
// to localize path as a root.
if fileErr == nil {
_, resErr := lc.rFactory.NewResMapFromBytes(content)
if resErr != nil {
fileErr = errors.WrapPrefixf(resErr, "invalid resource at file %q", path)
} else {
locPath, fileErr = lc.localizeFileWithContent(path, content)
}
}
if fileErr != nil {
var rootErr error
locPath, rootErr = lc.localizeRoot(path)
if rootErr != nil {
err := PathLocalizeError{
Path: path,
FileError: fileErr,
RootError: rootErr,
}
return "", err
}
}
return locPath, nil
}
// localizeFile localizes file path if set and returns the localized path
func (lc *localizer) localizeFile(path string) (string, error) {
// Some localizable fields can be empty, for example, replacements.path.
// We rely on the build command to throw errors for the ones that cannot.
if path == "" {
return "", nil
}
content, err := lc.ldr.Load(path)
if err != nil {
return "", errors.Wrap(err)
}
return lc.localizeFileWithContent(path, content)
}
// localizeFileWithContent writes content to the localized file path and returns the localized path.
func (lc *localizer) localizeFileWithContent(path string, content []byte) (string, error) {
var locPath string
if loader.IsRemoteFile(path) {
if lc.fSys.Exists(lc.root.Join(LocalizeDir)) {
return "", errors.Errorf("%s already contains %s needed to store file %q", lc.root, LocalizeDir, path)
}
locPath = locFilePath(path)
} else {
// ldr has checked that path must be relative; this is subject to change in beta.
// We must clean path to:
// 1. avoid symlinks. A `kustomize build` run will fail if we write files to
// symlink paths outside the current root, given that we don't want to recreate
// the symlinks. Even worse, we could be writing files outside the localize destination.
// 2. avoid paths that temporarily traverse outside the current root,
// i.e. ../../../scope/target/current-root. The localized file will be surrounded by
// different directories than its source, and so an uncleaned path may no longer be valid.
locPath = cleanFilePath(lc.fSys, lc.root, path)
}
absPath := filepath.Join(lc.dst, locPath)
if err := lc.fSys.MkdirAll(filepath.Dir(absPath)); err != nil {
return "", errors.WrapPrefixf(err, "unable to create directories to localize file %q", path)
}
if err := lc.fSys.WriteFile(absPath, content); err != nil {
return "", errors.WrapPrefixf(err, "unable to localize file %q", path)
}
return locPath, nil
}
// localizeRoot localizes root path if set and returns the localized path
func (lc *localizer) localizeRoot(path string) (string, error) {
if path == "" {
return "", nil
}
ldr, err := lc.ldr.New(path)
if err != nil {
return "", errors.Wrap(err)
}
defer func() { _ = ldr.Cleanup() }()
root, err := filesys.ConfirmDir(lc.fSys, ldr.Root())
if err != nil {
log.Panicf("unable to establish validated root reference %q: %s", path, err)
}
var locPath string
if repo := ldr.Repo(); repo != "" {
if lc.fSys.Exists(lc.root.Join(LocalizeDir)) {
return "", errors.Errorf("%s already contains %s needed to store root %q", lc.root, LocalizeDir, path)
}
locPath, err = locRootPath(path, repo, root, lc.fSys)
if err != nil {
return "", err
}
} else {
locPath, err = filepath.Rel(lc.root.String(), root.String())
if err != nil {
log.Panicf("cannot find relative path between scoped localize roots %q and %q: %s", lc.root, root, err)
}
}
newDst := filepath.Join(lc.dst, locPath)
if err = lc.fSys.MkdirAll(newDst); err != nil {
return "", errors.WrapPrefixf(err, "unable to create root %q in localize destination", path)
}
err = (&localizer{
fSys: lc.fSys,
ldr: ldr,
root: root,
rFactory: lc.rFactory,
dst: newDst,
}).localize()
if err != nil {
return "", errors.WrapPrefixf(err, "unable to localize root %q", path)
}
return locPath, nil
}
// copyChartHomeEntry copies the helm chart home entry to lc dst
// at the same location relative to the root and returns said relative path.
// If entry is empty, copyChartHomeEntry returns the empty string.
// If entry does not exist, copyChartHome returns entry.
//
// copyChartHomeEntry copies the default home to the same location at dst,
// without following symlinks. An empty entry also indicates the default home.
func (lc *localizer) copyChartHomeEntry(entry string) (string, error) {
path := entry
if entry == "" {
path = types.HelmDefaultHome
}
if filepath.IsAbs(path) {
return "", errors.Errorf("absolute path %q not handled in alpha", path)
}
isDefault := lc.root.Join(path) == lc.root.Join(types.HelmDefaultHome)
locPath, err := lc.copyChartHome(path, !isDefault)
if err != nil {
return "", errors.WrapPrefixf(err, "unable to copy home %q", entry)
}
if entry == "" {
return "", nil
}
return locPath, nil
}
// copyChartHome copies path relative to lc root to dst and returns the
// copied location relative to dst. If clean is true, copyChartHome uses path's
// delinked location as the copy destination.
//
// If path does not exist, copyChartHome returns path.
func (lc *localizer) copyChartHome(path string, clean bool) (string, error) {
path, err := filepath.Rel(lc.root.String(), lc.root.Join(path))
if err != nil {
return "", errors.WrapPrefixf(err, "no path to chart home %q", path)
}
// Chart home may serve as untar destination.
// Note that we don't check if path is in scope.
if !lc.fSys.Exists(lc.root.Join(path)) {
return path, nil
}
// Perform localize directory checks.
ldr, err := lc.ldr.New(path)
if err != nil {
return "", errors.WrapPrefixf(err, "invalid chart home")
}
cleaned, err := filesys.ConfirmDir(lc.fSys, ldr.Root())
if err != nil {
log.Panicf("unable to confirm validated directory %q: %s", ldr.Root(), err)
}
toDst := path
if clean {
toDst, err = filepath.Rel(lc.root.String(), cleaned.String())
if err != nil {
log.Panicf("no path between scoped directories %q and %q: %s", lc.root, cleaned, err)
}
}
// Note this check does not guarantee that we copied the entire directory.
if dst := filepath.Join(lc.dst, toDst); !lc.fSys.Exists(dst) {
err = lc.copyDir(cleaned, filepath.Join(lc.dst, toDst))
if err != nil {
return "", errors.WrapPrefixf(err, "unable to copy chart home %q", path)
}
}
return toDst, nil
}
// copyDir copies src to dst. copyDir does not follow symlinks.
func (lc *localizer) copyDir(src filesys.ConfirmedDir, dst string) error {
err := lc.fSys.Walk(src.String(),
func(path string, info fs.FileInfo, err error) error {
if err != nil {
return err
}
pathToCreate, err := filepath.Rel(src.String(), path)
if err != nil {
log.Panicf("no path from %q to child file %q: %s", src, path, err)
}
pathInDst := filepath.Join(dst, pathToCreate)
if info.Mode()&os.ModeSymlink == os.ModeSymlink {
return nil
}
if info.IsDir() {
err = lc.fSys.MkdirAll(pathInDst)
} else {
var content []byte
content, err = lc.fSys.ReadFile(path)
if err != nil {
return errors.Wrap(err)
}
err = lc.fSys.WriteFile(pathInDst, content)
}
return errors.Wrap(err)
})
if err != nil {
return errors.WrapPrefixf(err, "unable to copy directory %q", src)
}
return nil
}
// localizeBuiltinPlugins localizes built-in plugins on kust that can contain file paths. The built-in plugins
// can be inline or in a file. This excludes the HelmChartInflationGenerator.
//
// Note that the localization in this function has not been implemented yet.
func (lc *localizer) localizeBuiltinPlugins(kust *types.Kustomization) error {
for fieldName, entries := range map[string][]string{
"generators": kust.Generators,
"transformers": kust.Transformers,
"validators": kust.Validators,
} {
for i, entry := range entries {
rm, isPath, err := lc.loadK8sResource(entry)
if err != nil {
return errors.WrapPrefixf(err, "unable to load %s entry", fieldName)
}
err = rm.ApplyFilter(&localizeBuiltinPlugins{lc: lc})
if err != nil {
return errors.Wrap(err)
}
localizedPlugin, err := rm.AsYaml()
if err != nil {
return errors.WrapPrefixf(err, "unable to serialize localized %s entry %q", fieldName, entry)
}
var localizedEntry string
if isPath {
localizedEntry, err = lc.localizeFileWithContent(entry, localizedPlugin)
if err != nil {
return errors.WrapPrefixf(err, "unable to localize %s entry", fieldName)
}
} else {
localizedEntry = string(localizedPlugin)
}
entries[i] = localizedEntry
}
}
return nil
}
// localizeK8sResource returns the localized resourceEntry if it is a file
// containing a kubernetes resource.
// localizeK8sResource returns resourceEntry if it is an inline resource.
func (lc *localizer) localizeK8sResource(resourceEntry string) (string, error) {
_, isFile, err := lc.loadK8sResource(resourceEntry)
if err != nil {
return "", err
}
if isFile {
return lc.localizeFile(resourceEntry)
}
return resourceEntry, nil
}
// loadK8sResource tries to load resourceEntry as a file path or inline
// kubernetes resource.
// On success, loadK8sResource returns the loaded resource map and whether
// resourceEntry is a file path.
func (lc *localizer) loadK8sResource(resourceEntry string) (resmap.ResMap, bool, error) {
rm, inlineErr := lc.rFactory.NewResMapFromBytes([]byte(resourceEntry))
if inlineErr != nil {
var fileErr error
rm, fileErr = lc.rFactory.FromFile(lc.ldr, resourceEntry)
if fileErr != nil {
err := ResourceLoadError{
InlineError: inlineErr,
FileError: fileErr,
}
return nil, false, errors.WrapPrefixf(err, "unable to load resource entry %q", resourceEntry)
}
}
return rm, inlineErr != nil, nil
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,135 @@
// Copyright 2022 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package localizer
import (
"path/filepath"
"sigs.k8s.io/kustomize/api/ifc"
"sigs.k8s.io/kustomize/api/internal/git"
"sigs.k8s.io/kustomize/api/internal/loader"
"sigs.k8s.io/kustomize/kyaml/errors"
"sigs.k8s.io/kustomize/kyaml/filesys"
)
// Args holds localize arguments
type Args struct {
// target; local copy if remote
Target filesys.ConfirmedDir
// directory that bounds target's local references
// repo directory of local copy if target is remote
Scope filesys.ConfirmedDir
// localize destination
NewDir filesys.ConfirmedDir
}
// Loader is an ifc.Loader that enforces additional constraints specific to kustomize localize.
type Loader struct {
fSys filesys.FileSystem
args *Args
// loader at Loader's current directory
ifc.Loader
// whether Loader and all its ancestors are the result of local references
local bool
}
var _ ifc.Loader = &Loader{}
// NewLoader is the factory method for Loader, under localize constraints, at rawTarget. For invalid localize arguments,
// NewLoader returns an error.
func NewLoader(rawTarget string, rawScope string, rawNewDir string, fSys filesys.FileSystem) (*Loader, Args, error) {
// check earlier to avoid cleanup
repoSpec, err := git.NewRepoSpecFromURL(rawTarget)
if err == nil && repoSpec.Ref == "" {
return nil, Args{}, errors.Errorf("localize remote root %q missing ref query string parameter", rawTarget)
}
// for security, should enforce load restrictions
ldr, err := loader.NewLoader(loader.RestrictionRootOnly, rawTarget, fSys)
if err != nil {
return nil, Args{}, errors.WrapPrefixf(err, "unable to establish localize target %q", rawTarget)
}
scope, err := establishScope(rawScope, rawTarget, ldr, fSys)
if err != nil {
_ = ldr.Cleanup()
return nil, Args{}, errors.WrapPrefixf(err, "invalid localize scope %q", rawScope)
}
newDir, err := createNewDir(rawNewDir, ldr, repoSpec, fSys)
if err != nil {
_ = ldr.Cleanup()
return nil, Args{}, errors.WrapPrefixf(err, "invalid localize destination %q", rawNewDir)
}
args := Args{
Target: filesys.ConfirmedDir(ldr.Root()),
Scope: scope,
NewDir: newDir,
}
return &Loader{
fSys: fSys,
args: &args,
Loader: ldr,
local: scope != "",
}, args, nil
}
// Load returns the contents of path if path is a valid localize file.
// Otherwise, Load returns an error.
func (ll *Loader) Load(path string) ([]byte, error) {
// checks in root, and thus in scope
content, err := ll.Loader.Load(path)
if err != nil {
return nil, errors.WrapPrefixf(err, "invalid file reference")
}
if filepath.IsAbs(path) {
return nil, errors.Errorf("absolute paths not yet supported in alpha: file path %q is absolute", path)
}
if !loader.IsRemoteFile(path) && ll.local {
cleanPath := cleanFilePath(ll.fSys, filesys.ConfirmedDir(ll.Root()), path)
cleanAbs := filepath.Join(ll.Root(), cleanPath)
dir := filesys.ConfirmedDir(filepath.Dir(cleanAbs))
// target cannot reference newDir, as this load would've failed prior to localize;
// not a problem if remote because then reference could only be in newDir if repo copy,
// which will be cleaned, is inside newDir
if dir.HasPrefix(ll.args.NewDir) {
return nil, errors.Errorf("file %q at %q enters localize destination %q", path, cleanAbs, ll.args.NewDir)
}
}
return content, nil
}
// New returns a Loader at path if path is a valid localize root.
// Otherwise, New returns an error.
func (ll *Loader) New(path string) (ifc.Loader, error) {
ldr, err := ll.Loader.New(path)
if err != nil {
return nil, errors.WrapPrefixf(err, "invalid root reference")
}
if repo := ldr.Repo(); repo == "" {
if ll.local && !filesys.ConfirmedDir(ldr.Root()).HasPrefix(ll.args.Scope) {
return nil, errors.Errorf("root %q outside localize scope %q", ldr.Root(), ll.args.Scope)
}
if ll.local && filesys.ConfirmedDir(ldr.Root()).HasPrefix(ll.args.NewDir) {
return nil, errors.Errorf(
"root %q references into localize destination %q", ldr.Root(), ll.args.NewDir)
}
} else if !hasRef(path) {
return nil, errors.Errorf("localize remote root %q missing ref query string parameter", path)
}
return &Loader{
fSys: ll.fSys,
args: ll.args,
Loader: ldr,
local: ll.local && ldr.Repo() == "",
}, nil
}

View File

@@ -0,0 +1,300 @@
// Copyright 2022 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package localizer_test
import (
"bytes"
"log"
"os"
"testing"
"github.com/stretchr/testify/require"
"sigs.k8s.io/kustomize/api/ifc"
. "sigs.k8s.io/kustomize/api/internal/localizer"
"sigs.k8s.io/kustomize/kyaml/filesys"
)
func checkNewLoader(req *require.Assertions, ldr *Loader, args *Args, target string, scope string, newDir string, fSys filesys.FileSystem) {
checkLoader(req, ldr, target)
checkArgs(req, args, target, scope, newDir, fSys)
}
func checkLoader(req *require.Assertions, ldr ifc.Loader, root string) {
req.Equal(root, ldr.Root())
req.Empty(ldr.Repo())
}
func checkArgs(req *require.Assertions, args *Args, target string, scope string, newDir string, fSys filesys.FileSystem) {
req.Equal(target, args.Target.String())
req.Equal(scope, args.Scope.String())
req.Equal(newDir, args.NewDir.String())
req.True(fSys.Exists(newDir))
}
func TestLocalLoadNewAndCleanup(t *testing.T) {
req := require.New(t)
fSys := makeMemoryFs(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)
checkNewLoader(req, ldr, &args, "/a", "/", "/newDir", fSys)
fSysCopy := makeMemoryFs(t)
req.NoError(fSysCopy.Mkdir("/newDir"))
req.Equal(fSysCopy, fSys)
// easy load directly in root
content, err := ldr.Load("pod.yaml")
req.NoError(err)
req.Equal([]byte(podConfiguration), content)
// typical sibling root reference
sibLdr, err := ldr.New("../alpha")
req.NoError(err)
checkLoader(req, sibLdr, "/alpha")
// only need to test once, since don't need to call Cleanup() on local target
req.NoError(sibLdr.Cleanup())
req.NoError(ldr.Cleanup())
// file system and buffer checks are also one-time
req.Equal(fSysCopy, fSys)
req.Empty(buf.String())
}
func TestNewLocLoaderDefaultForRootTarget(t *testing.T) {
cases := map[string]struct {
target string
scope string
}{
"explicit": {
"/",
".",
},
"implicit": {
".",
"",
},
}
for name, params := range cases {
params := params
t.Run(name, func(t *testing.T) {
req := require.New(t)
fSys := makeMemoryFs(t)
ldr, args, err := NewLoader(params.target, params.scope, "", fSys)
req.NoError(err)
checkNewLoader(req, ldr, &args, "/", "/", "/"+DstPrefix, fSys)
// file in root, but nested
content, err := ldr.Load("a/pod.yaml")
req.NoError(err)
req.Equal([]byte(podConfiguration), content)
childLdr, err := ldr.New("a")
req.NoError(err)
checkLoader(req, childLdr, "/a")
// messy, uncleaned path
content, err = childLdr.Load("./../a/pod.yaml")
req.NoError(err)
req.Equal([]byte(podConfiguration), content)
})
}
}
func TestNewMultiple(t *testing.T) {
req := require.New(t)
fSys := makeMemoryFs(t)
// default destination for non-file system root target
// destination outside of scope
ldr, args, err := NewLoader("/alpha/beta", "/alpha", "", fSys)
req.NoError(err)
checkNewLoader(req, ldr, &args, "/alpha/beta", "/alpha", "/"+DstPrefix+"-beta", fSys)
// nested child root that isn't cleaned
descLdr, err := ldr.New("../beta/gamma/delta")
req.NoError(err)
checkLoader(req, descLdr, "/alpha/beta/gamma/delta")
// upwards traversal
higherLdr, err := descLdr.New("../../say")
req.NoError(err)
checkLoader(req, higherLdr, "/alpha/beta/say")
}
func makeWdFs(t *testing.T) map[string]filesys.FileSystem {
t.Helper()
req := require.New(t)
root := filesys.MakeEmptyDirInMemory()
req.NoError(root.MkdirAll("a/b/c/d/e"))
outer, err := root.Find("a")
req.NoError(err)
middle, err := root.Find("a/b/c")
req.NoError(err)
return map[string]filesys.FileSystem{
"a": outer,
"a/b/c": middle,
}
}
func TestNewLocLoaderCwdNotRoot(t *testing.T) {
cases := map[string]struct {
wd string
target string
scope string
newDir string
}{
// target not immediate child of scope
"outer dir": {
"a",
"b/c/d/e",
"b/c",
"b/newDir",
},
"scope": {
"a/b/c",
"d/e",
".",
"d/e/newDir",
},
}
for name, test := range cases {
test := test
t.Run(name, func(t *testing.T) {
req := require.New(t)
fSys := makeWdFs(t)[test.wd]
ldr, args, err := NewLoader(test.target, test.scope, test.newDir, fSys)
req.NoError(err)
checkLoader(req, ldr, "a/b/c/d/e")
req.Equal("a/b/c/d/e", args.Target.String())
req.Equal("a/b/c", args.Scope.String())
req.Equal(test.wd+"/"+test.newDir, args.NewDir.String())
// memory file system can only find paths rooted at current node
req.True(fSys.Exists(test.newDir))
})
}
}
func TestNewLocLoaderFails(t *testing.T) {
cases := map[string]struct {
target string
scope string
dest string
}{
"non-existent target": {
"/b",
"/",
"/newDir",
},
"file target": {
"/a/pod.yaml",
"/",
"/newDir",
},
"inner scope": {
"/alpha",
"/alpha/beta",
"/newDir",
},
"side scope": {
"/alpha",
"/a",
"/newDir",
},
"existing dst": {
"/alpha",
"/",
"/a",
},
}
for name, params := range cases {
params := params
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)
require.Empty(t, buf.String())
})
}
}
func TestNewFails(t *testing.T) {
req := require.New(t)
fSys := makeMemoryFs(t)
ldr, args, err := NewLoader("/alpha/beta/gamma", "alpha", "alpha/beta/gamma/newDir", fSys)
req.NoError(err)
checkNewLoader(req, ldr, &args, "/alpha/beta/gamma", "/alpha", "/alpha/beta/gamma/newDir", fSys)
cases := map[string]string{
"outside scope": "../../../a",
"at dst": "newDir",
"ancestor": "../../beta",
"non-existent root": "delt",
"file": "delta/deployment.yaml",
}
for name, root := range cases {
root := root
t.Run(name, func(t *testing.T) {
fSys := makeMemoryFs(t)
ldr, _, err := NewLoader("/alpha/beta/gamma", "alpha", "alpha/beta/gamma/newDir", fSys)
require.NoError(t, err)
_, err = ldr.New(root)
require.Error(t, err)
})
}
}
func TestLoadFails(t *testing.T) {
req := require.New(t)
fSys := makeMemoryFs(t)
ldr, args, err := NewLoader("./a/../a", "/a/../a", "/a/newDir", fSys)
req.NoError(err)
checkNewLoader(req, ldr, &args, "/a", "/a", "/a/newDir", fSys)
cases := map[string]string{
"absolute path": "/a/pod.yaml",
"directory": "b",
"non-existent file": "kubectl.yaml",
"file outside root": "../alpha/beta/gamma/delta/deployment.yaml",
"inside dst": "newDir/pod.yaml",
}
for name, file := range cases {
file := file
t.Run(name, func(t *testing.T) {
req := require.New(t)
fSys := makeMemoryFs(t)
ldr, _, err := NewLoader("./a/../a", "/a/../a", "/a/newDir", fSys)
req.NoError(err)
req.NoError(fSys.WriteFile("/a/newDir/pod.yaml", []byte(podConfiguration)))
_, err = ldr.Load(file)
req.Error(err)
})
}
}

View File

@@ -0,0 +1,218 @@
// Copyright 2022 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package localizer
import (
"log"
"net/url"
"path/filepath"
"strings"
"sigs.k8s.io/kustomize/api/ifc"
"sigs.k8s.io/kustomize/api/internal/git"
"sigs.k8s.io/kustomize/kyaml/errors"
"sigs.k8s.io/kustomize/kyaml/filesys"
)
const (
// DstPrefix prefixes the target and ref, if target is remote, in the default localize destination directory name
DstPrefix = "localized"
// LocalizeDir is the name of the localize directories used to store remote content in the localize destination
LocalizeDir = "localized-files"
// FileSchemeDir is the name of the directory immediately inside LocalizeDir used to store file-schemed repos
FileSchemeDir = "file-schemed"
)
// establishScope returns the effective scope given localize arguments and targetLdr at rawTarget. For remote rawTarget,
// the effective scope is the downloaded repo.
func establishScope(rawScope string, rawTarget string, targetLdr ifc.Loader, fSys filesys.FileSystem) (filesys.ConfirmedDir, error) {
if repo := targetLdr.Repo(); repo != "" {
if rawScope != "" {
return "", errors.Errorf("scope %q specified for remote localize target %q", rawScope, rawTarget)
}
return filesys.ConfirmedDir(repo), nil
}
// default scope
if rawScope == "" {
return filesys.ConfirmedDir(targetLdr.Root()), nil
}
scope, err := filesys.ConfirmDir(fSys, rawScope)
if err != nil {
return "", errors.WrapPrefixf(err, "unable to establish localize scope")
}
if !filesys.ConfirmedDir(targetLdr.Root()).HasPrefix(scope) {
return scope, errors.Errorf("localize scope %q does not contain target %q at %q", rawScope, rawTarget,
targetLdr.Root())
}
return scope, nil
}
// createNewDir returns the localize destination directory or error. Note that spec is nil if targetLdr is at local
// target.
func createNewDir(rawNewDir string, targetLdr ifc.Loader, spec *git.RepoSpec, fSys filesys.FileSystem) (filesys.ConfirmedDir, error) {
if rawNewDir == "" {
rawNewDir = defaultNewDir(targetLdr, spec)
}
if fSys.Exists(rawNewDir) {
return "", errors.Errorf("localize destination %q already exists", rawNewDir)
}
// destination directory must sit in an existing directory
if err := fSys.Mkdir(rawNewDir); err != nil {
return "", errors.WrapPrefixf(err, "unable to create localize destination directory")
}
newDir, err := filesys.ConfirmDir(fSys, rawNewDir)
if err != nil {
if errCleanup := fSys.RemoveAll(newDir.String()); errCleanup != nil {
log.Printf("%s", errors.WrapPrefixf(errCleanup, "unable to clean localize destination"))
}
return "", errors.WrapPrefixf(err, "unable to establish localize destination")
}
return newDir, nil
}
// defaultNewDir calculates the default localize destination directory name from targetLdr at the localize target
// and spec of target, which is nil if target is local
func defaultNewDir(targetLdr ifc.Loader, spec *git.RepoSpec) string {
targetDir := filepath.Base(targetLdr.Root())
if repo := targetLdr.Repo(); repo != "" {
// kustomize doesn't download repo into repo-named folder
// must find repo folder name from url
if repo == targetLdr.Root() {
targetDir = urlBase(spec.RepoPath)
}
return strings.Join([]string{DstPrefix, targetDir, strings.ReplaceAll(spec.Ref, "/", "-")}, "-")
}
// special case for local target directory since destination directory cannot have "/" in name
if targetDir == string(filepath.Separator) {
return DstPrefix
}
return strings.Join([]string{DstPrefix, targetDir}, "-")
}
// urlBase is the url equivalent of filepath.Base
func urlBase(url string) string {
cleaned := strings.TrimRight(url, "/")
i := strings.LastIndex(cleaned, "/")
if i < 0 {
return cleaned
}
return cleaned[i+1:]
}
// hasRef checks if repoURL has ref query string parameter
func hasRef(repoURL string) bool {
repoSpec, err := git.NewRepoSpecFromURL(repoURL)
if err != nil {
log.Fatalf("unable to parse validated root url: %s", err)
}
return repoSpec.Ref != ""
}
// cleanFilePath returns file cleaned, where file is a relative path to root on fSys
func cleanFilePath(fSys filesys.FileSystem, root filesys.ConfirmedDir, file string) string {
abs := root.Join(file)
dir, f, err := fSys.CleanedAbs(abs)
if err != nil {
log.Fatalf("cannot clean validated file path %q: %s", abs, err)
}
locPath, err := filepath.Rel(root.String(), dir.Join(f))
if err != nil {
log.Fatalf("cannot find path from parent %q to file %q: %s", root, dir.Join(f), err)
}
return locPath
}
// locFilePath converts a URL to its localized form, e.g.
// https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/api/krusty/testdata/localize/simple/service.yaml ->
// localized-files/raw.githubusercontent.com/kubernetes-sigs/kustomize/master/api/krusty/testdata/localize/simple/service.yaml.
//
// fileURL must be a validated file URL.
func locFilePath(fileURL string) string {
// File urls must have http or https scheme, so it is safe to use url.Parse.
u, err := url.Parse(fileURL)
if err != nil {
log.Panicf("cannot parse validated file url %q: %s", fileURL, err)
}
// HTTP requests use the escaped path, so we use it here. Escaped paths also help us
// preserve percent-encoding in the original path, in the absence of illegal characters,
// in case they have special meaning to the host.
// Extraneous '..' parent directory dot-segments should be removed.
path := filepath.Join(string(filepath.Separator), filepath.FromSlash(u.EscapedPath()))
// We intentionally exclude userinfo and port.
// Raw github urls are the only type of file urls kustomize officially accepts.
// In this case, the path already consists of org, repo, version, and path in repo, in order,
// so we can use it as is.
return filepath.Join(LocalizeDir, u.Hostname(), path)
}
// locRootPath returns the relative localized path of the validated root url rootURL, where the local copy of its repo
// is at repoDir and the copy of its root is at root on fSys.
func locRootPath(rootURL, repoDir string, root filesys.ConfirmedDir, fSys filesys.FileSystem) (string, error) {
repoSpec, err := git.NewRepoSpecFromURL(rootURL)
if err != nil {
log.Panicf("cannot parse validated repo url %q: %s", rootURL, err)
}
host, err := parseHost(repoSpec)
if err != nil {
return "", errors.WrapPrefixf(err, "unable to parse host of remote root %q", rootURL)
}
repo, err := filesys.ConfirmDir(fSys, repoDir)
if err != nil {
log.Panicf("unable to establish validated repo download location %q: %s", repoDir, err)
}
// calculate from copy instead of url to straighten symlinks
inRepo, err := filepath.Rel(repo.String(), root.String())
if err != nil {
log.Panicf("cannot find path from %q to child directory %q: %s", repo, root, err)
}
// the git-server-side directory name conventionally (but not universally) ends in .git, which
// is conventionally stripped from the client-side directory name used for the clone.
localRepoPath := strings.TrimSuffix(repoSpec.RepoPath, ".git")
// We do not need to escape RepoPath, a path on the git server.
// However, like git, we clean dot-segments from RepoPath.
// Git does not allow ref value to contain dot-segments.
return filepath.Join(LocalizeDir,
host,
filepath.Join(string(filepath.Separator), filepath.FromSlash(localRepoPath)),
filepath.FromSlash(repoSpec.Ref),
inRepo), nil
}
// parseHost returns the localize directory path corresponding to repoSpec.Host
func parseHost(repoSpec *git.RepoSpec) (string, error) {
var target string
switch scheme, _, _ := strings.Cut(repoSpec.Host, "://"); scheme {
case "gh:":
// 'gh' was meant to be a local github.com shorthand, in which case
// the .gitconfig file could map it to any host. See origin here:
// https://github.com/kubernetes-sigs/kustomize/blob/kustomize/v4.5.7/api/internal/git/repospec.go#L203
// We give it a special host directory here under the assumption
// that we are unlikely to have another host simply named 'gh'.
return "gh", nil
case "file":
// We put file-scheme repos under a special directory to avoid
// colluding local absolute paths with hosts.
return FileSchemeDir, nil
case "https", "http", "ssh":
target = repoSpec.Host
default:
// We must have relative ssh url; in other words, the url has scp-like syntax.
// We attach a scheme to avoid url.Parse errors.
target = "ssh://" + repoSpec.Host
}
// url.Parse will not recognize ':' delimiter that both RepoSpec and git accept.
target = strings.TrimSuffix(target, ":")
u, err := url.Parse(target)
if err != nil {
return "", errors.Wrap(err)
}
// strip scheme, userinfo, port, and any trailing slashes.
return u.Hostname(), nil
}

View File

@@ -0,0 +1,303 @@
// Copyright 2022 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package localizer //nolint:testpackage
import (
"fmt"
"os"
"path/filepath"
"strings"
"testing"
"github.com/stretchr/testify/require"
"sigs.k8s.io/kustomize/api/ifc"
"sigs.k8s.io/kustomize/api/internal/git"
"sigs.k8s.io/kustomize/kyaml/filesys"
)
func TestDefaultNewDirRepo(t *testing.T) {
for name, test := range map[string]struct {
url, dst string
}{
"simple": {
url: "https://github.com/org/repo?ref=value",
dst: "localized-repo-value",
},
"slashed_ref": {
url: "https://github.com/org/repo?ref=group/version",
dst: "localized-repo-group-version",
},
} {
t.Run(name, func(t *testing.T) {
repoSpec, err := git.NewRepoSpecFromURL(test.url)
require.NoError(t, err)
require.Equal(t, test.dst, defaultNewDir(&fakeLoader{t.TempDir()}, repoSpec))
})
}
}
type fakeLoader struct {
root string
}
func (fl *fakeLoader) Root() string {
return fl.root
}
func (fl *fakeLoader) Repo() string {
return fl.root
}
func (fl *fakeLoader) Load(_ string) ([]byte, error) {
return []byte{}, nil
}
func (fl *fakeLoader) New(path string) (ifc.Loader, error) {
return &fakeLoader{path}, nil
}
func (fl *fakeLoader) Cleanup() error {
return nil
}
func TestUrlBase(t *testing.T) {
require.Equal(t, "repo", urlBase("https://github.com/org/repo"))
}
func TestUrlBaseTrailingSlash(t *testing.T) {
require.Equal(t, "repo", urlBase("github.com/org/repo//"))
}
// simpleJoin is filepath.Join() without the side effects of filepath.Clean()
func simpleJoin(t *testing.T, elems ...string) string {
t.Helper()
return strings.Join(elems, string(filepath.Separator))
}
func TestLocFilePath(t *testing.T) {
for name, tUnit := range map[string]struct {
url, path string
}{
"official": {
url: "https://raw.githubusercontent.com/org/repo/ref/path/to/file.yaml",
path: simpleJoin(t, "raw.githubusercontent.com", "org", "repo", "ref", "path", "to", "file.yaml"),
},
"http-scheme": {
url: "http://host/path",
path: simpleJoin(t, "host", "path"),
},
"extraneous_components": {
url: "http://userinfo@host:1234/path/file?query",
path: simpleJoin(t, "host", "path", "file"),
},
"empty_path": {
url: "https://host",
path: "host",
},
"empty_path_segment": {
url: "https://host//",
path: "host",
},
"percent-encoded_path": {
url: "https://host/file%2Eyaml",
path: simpleJoin(t, "host", "file%2Eyaml"),
},
"dot-segments": {
url: "https://host/path/blah/../to/foo/bar/../../file/./",
path: simpleJoin(t, "host", "path", "to", "file"),
},
"extraneous_dot-segments": {
url: "https://host/foo/bar/baz/../../../../file",
path: simpleJoin(t, "host", "file"),
},
} {
t.Run(name, func(t *testing.T) {
require.Equal(t, simpleJoin(t, LocalizeDir, tUnit.path), locFilePath(tUnit.url))
})
}
}
func TestLocFilePathColon(t *testing.T) {
req := require.New(t)
// The colon is special because it was once used as the unix file separator.
const url = "https://[2001:4860:4860::8888]/file.yaml"
const host = "2001:4860:4860::8888"
const file = "file.yaml"
req.Equal(simpleJoin(t, LocalizeDir, host, file), locFilePath(url))
fSys := filesys.MakeFsOnDisk()
targetDir := simpleJoin(t, t.TempDir(), host)
// We check that we can create single directory, meaning ':' not used as file separator.
req.NoError(fSys.Mkdir(targetDir))
_, err := fSys.Create(simpleJoin(t, targetDir, file))
req.NoError(err)
// We check that the directory with such name is readable.
files, err := fSys.ReadDir(targetDir)
req.NoError(err)
req.Equal([]string{file}, files)
}
func TestLocFilePath_SpecialChar(t *testing.T) {
req := require.New(t)
// The wild card character is one of the legal uri characters with more meaning
// to the system, so we test it here.
const wildcard = "*"
req.Equal(simpleJoin(t, LocalizeDir, "host", wildcard), locFilePath("https://host/*"))
fSys := filesys.MakeFsOnDisk()
testDir := t.TempDir()
req.NoError(fSys.Mkdir(simpleJoin(t, testDir, "a")))
req.NoError(fSys.WriteFile(simpleJoin(t, testDir, "b"), []byte{}))
// We check that we can create and read from wild card-named file.
// We check that the file system is not matching it to existing file names.
req.NoError(fSys.WriteFile(simpleJoin(t, testDir, wildcard), []byte("test")))
content, err := fSys.ReadFile(simpleJoin(t, testDir, wildcard))
req.NoError(err)
req.Equal("test", string(content))
}
func TestLocFilePath_SpecialFiles(t *testing.T) {
for name, tFSys := range map[string]struct {
urlPath string
pathDir, pathFile string
}{
"windows_reserved_name": {
urlPath: "/aux/file",
pathDir: "aux",
pathFile: "file",
},
"hidden_files": {
urlPath: "/.../.file",
pathDir: "...",
pathFile: ".file",
},
} {
t.Run(name, func(t *testing.T) {
req := require.New(t)
expectedPath := simpleJoin(t, LocalizeDir, "host", tFSys.pathDir, tFSys.pathFile)
req.Equal(expectedPath, locFilePath("https://host"+tFSys.urlPath))
fSys := filesys.MakeFsOnDisk()
targetDir := simpleJoin(t, t.TempDir(), tFSys.pathDir)
req.NoError(fSys.Mkdir(targetDir))
req.NoError(fSys.WriteFile(simpleJoin(t, targetDir, tFSys.pathFile), []byte("test")))
content, err := fSys.ReadFile(simpleJoin(t, targetDir, tFSys.pathFile))
req.NoError(err)
req.Equal([]byte("test"), content)
})
}
}
func makeConfirmedDir(t *testing.T) (filesys.FileSystem, filesys.ConfirmedDir) {
t.Helper()
fSys := filesys.MakeFsOnDisk()
testDir, err := filesys.NewTmpConfirmedDir()
require.NoError(t, err)
t.Cleanup(func() {
_ = fSys.RemoveAll(testDir.String())
})
return fSys, testDir
}
func TestLocRootPath_URLComponents(t *testing.T) {
for name, test := range map[string]struct {
urlf, path string
}{
"ssh": {
urlf: "ssh://git@github.com/org/repo//%s?ref=value",
path: simpleJoin(t, "github.com", "org", "repo", "value"),
},
"rel_ssh": {
urlf: "git@github.com:org/repo//%s?ref=value",
path: simpleJoin(t, "github.com", "org", "repo", "value"),
},
"https": {
urlf: "https://gitlab.com/org/repo//%s?ref=value",
path: simpleJoin(t, "gitlab.com", "org", "repo", "value"),
},
"file": {
urlf: "file:///var/run/repo//%s?ref=value",
path: simpleJoin(t, FileSchemeDir, "var", "run", "repo", "value"),
},
"IPv6": {
urlf: "https://[2001:4860:4860::8888]/org/repo//%s?ref=value",
path: simpleJoin(t, "2001:4860:4860::8888", "org", "repo", "value"),
},
"port": {
urlf: "https://localhost.com:8080/org/repo//%s?ref=value",
path: simpleJoin(t, "localhost.com", "org", "repo", "value"),
},
"no_org": {
urlf: "https://github.com/repo//%s?ref=value",
path: simpleJoin(t, "github.com", "repo", "value"),
},
".git_suffix": {
urlf: "https://github.com/org1/org2/repo.git//%s?ref=value",
path: simpleJoin(t, "github.com", "org1", "org2", "repo", "value"),
},
"dot-segments": {
urlf: "https://github.com/./../org/../org/repo.git//%s?ref=value",
path: simpleJoin(t, "github.com", "org", "repo", "value"),
},
"no_path_delimiter": {
urlf: "https://github.com/org/repo/%s?ref=value",
path: simpleJoin(t, "github.com", "org", "repo", "value"),
},
"illegal_windows_dir": {
urlf: "https://gitlab.com/org./repo..git//%s?ref=value",
path: simpleJoin(t, "gitlab.com", "org.", "repo.", "value"),
},
"ref_has_slash": {
urlf: "https://gitlab.com/org/repo//%s?ref=group/version/kind",
path: simpleJoin(t, "gitlab.com", "org", "repo", "group", "version", "kind"),
},
} {
t.Run(name, func(t *testing.T) {
u := fmt.Sprintf(test.urlf, "path/to/root")
path := simpleJoin(t, LocalizeDir, test.path, "path", "to", "root")
fSys, testDir := makeConfirmedDir(t)
repoDir := simpleJoin(t, testDir.String(), "repo_random-hash")
require.NoError(t, fSys.Mkdir(repoDir))
rootDir := simpleJoin(t, repoDir, "path", "to", "root")
require.NoError(t, fSys.MkdirAll(rootDir))
actual, err := locRootPath(u, repoDir, filesys.ConfirmedDir(rootDir), fSys)
require.NoError(t, err)
require.Equal(t, path, actual)
require.NoError(t, fSys.MkdirAll(simpleJoin(t, testDir.String(), path)))
})
}
}
func TestLocRootPath_Repo(t *testing.T) {
const url = "https://github.com/org/repo?ref=value"
expected := simpleJoin(t, LocalizeDir, "github.com", "org", "repo", "value")
fSys, testDir := makeConfirmedDir(t)
actual, err := locRootPath(url, testDir.String(), testDir, fSys)
require.NoError(t, err)
require.Equal(t, expected, actual)
}
func TestLocRootPath_SymlinkPath(t *testing.T) {
const url = "https://github.com/org/repo//symlink?ref=value"
fSys, repoDir := makeConfirmedDir(t)
rootDir := simpleJoin(t, repoDir.String(), "actual-root")
require.NoError(t, fSys.Mkdir(rootDir))
require.NoError(t, os.Symlink(rootDir, simpleJoin(t, repoDir.String(), "symlink")))
expected := simpleJoin(t, LocalizeDir, "github.com", "org", "repo", "value", "actual-root")
actual, err := locRootPath(url, repoDir.String(), filesys.ConfirmedDir(rootDir), fSys)
require.NoError(t, err)
require.Equal(t, expected, actual)
}

View File

@@ -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"

View File

@@ -22,7 +22,7 @@ import (
// contains a Pod; Deployment, Job, StatefulSet, etc.
// The ConfigMap is the ReferralTarget, the others are Referrers.
//
// If the the name of a ConfigMap instance changed from 'alice' to 'bob',
// If the name of a ConfigMap instance changed from 'alice' to 'bob',
// one must
// - visit all objects that could refer to the ConfigMap (the Referrers)
// - see if they mention 'alice',

View File

@@ -8,8 +8,9 @@ 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"
)
// TransformerConfig holds the data needed to perform transformations.
@@ -18,6 +19,7 @@ type TransformerConfig struct {
NameSuffix types.FsSlice `json:"nameSuffix,omitempty" yaml:"nameSuffix,omitempty"`
NameSpace types.FsSlice `json:"namespace,omitempty" yaml:"namespace,omitempty"`
CommonLabels types.FsSlice `json:"commonLabels,omitempty" yaml:"commonLabels,omitempty"`
TemplateLabels types.FsSlice `json:"templateLabels,omitempty" yaml:"templateLabels,omitempty"`
CommonAnnotations types.FsSlice `json:"commonAnnotations,omitempty" yaml:"commonAnnotations,omitempty"`
NameReference nbrSlice `json:"nameReference,omitempty" yaml:"nameReference,omitempty"`
VarReference types.FsSlice `json:"varReference,omitempty" yaml:"varReference,omitempty"`
@@ -58,8 +60,10 @@ func MakeTransformerConfig(
// sortFields provides determinism in logging, tests, etc.
func (t *TransformerConfig) sortFields() {
sort.Sort(t.NamePrefix)
sort.Sort(t.NameSuffix)
sort.Sort(t.NameSpace)
sort.Sort(t.CommonLabels)
sort.Sort(t.TemplateLabels)
sort.Sort(t.CommonAnnotations)
sort.Sort(t.NameReference)
sort.Sort(t.VarReference)
@@ -108,40 +112,44 @@ func (t *TransformerConfig) Merge(input *TransformerConfig) (
merged = &TransformerConfig{}
merged.NamePrefix, err = t.NamePrefix.MergeAll(input.NamePrefix)
if err != nil {
return nil, err
return nil, errors.WrapPrefixf(err, "failed to merge NamePrefix fieldSpec")
}
merged.NameSuffix, err = t.NameSuffix.MergeAll(input.NameSuffix)
if err != nil {
return nil, err
return nil, errors.WrapPrefixf(err, "failed to merge NameSuffix fieldSpec")
}
merged.NameSpace, err = t.NameSpace.MergeAll(input.NameSpace)
if err != nil {
return nil, err
return nil, errors.WrapPrefixf(err, "failed to merge NameSpace fieldSpec")
}
merged.CommonAnnotations, err = t.CommonAnnotations.MergeAll(
input.CommonAnnotations)
if err != nil {
return nil, err
return nil, errors.WrapPrefixf(err, "failed to merge CommonAnnotations fieldSpec")
}
merged.CommonLabels, err = t.CommonLabels.MergeAll(input.CommonLabels)
if err != nil {
return nil, err
return nil, errors.WrapPrefixf(err, "failed to merge CommonLabels fieldSpec")
}
merged.TemplateLabels, err = t.TemplateLabels.MergeAll(input.TemplateLabels)
if err != nil {
return nil, errors.WrapPrefixf(err, "failed to merge TemplateLabels fieldSpec")
}
merged.VarReference, err = t.VarReference.MergeAll(input.VarReference)
if err != nil {
return nil, err
return nil, errors.WrapPrefixf(err, "failed to merge VarReference fieldSpec")
}
merged.NameReference, err = t.NameReference.mergeAll(input.NameReference)
if err != nil {
return nil, err
return nil, errors.WrapPrefixf(err, "failed to merge NameReference fieldSpec")
}
merged.Images, err = t.Images.MergeAll(input.Images)
if err != nil {
return nil, err
return nil, errors.WrapPrefixf(err, "failed to merge Images fieldSpec")
}
merged.Replicas, err = t.Replicas.MergeAll(input.Replicas)
if err != nil {
return nil, err
return nil, errors.WrapPrefixf(err, "failed to merge Replicas fieldSpec")
}
merged.sortFields()
return merged, nil

View File

@@ -15,24 +15,23 @@ func _() {
_ = x[HashTransformer-4]
_ = x[ImageTagTransformer-5]
_ = x[LabelTransformer-6]
_ = x[LegacyOrderTransformer-7]
_ = x[NamespaceTransformer-8]
_ = x[PatchJson6902Transformer-9]
_ = x[PatchStrategicMergeTransformer-10]
_ = x[PatchTransformer-11]
_ = x[PrefixSuffixTransformer-12]
_ = x[PrefixTransformer-13]
_ = x[SuffixTransformer-14]
_ = x[ReplicaCountTransformer-15]
_ = x[SecretGenerator-16]
_ = x[ValueAddTransformer-17]
_ = x[HelmChartInflationGenerator-18]
_ = x[ReplacementTransformer-19]
_ = x[NamespaceTransformer-7]
_ = x[PatchJson6902Transformer-8]
_ = x[PatchStrategicMergeTransformer-9]
_ = x[PatchTransformer-10]
_ = x[PrefixSuffixTransformer-11]
_ = x[PrefixTransformer-12]
_ = x[SuffixTransformer-13]
_ = x[ReplicaCountTransformer-14]
_ = x[SecretGenerator-15]
_ = x[ValueAddTransformer-16]
_ = x[HelmChartInflationGenerator-17]
_ = x[ReplacementTransformer-18]
}
const _BuiltinPluginType_name = "UnknownAnnotationsTransformerConfigMapGeneratorIAMPolicyGeneratorHashTransformerImageTagTransformerLabelTransformerLegacyOrderTransformerNamespaceTransformerPatchJson6902TransformerPatchStrategicMergeTransformerPatchTransformerPrefixSuffixTransformerPrefixTransformerSuffixTransformerReplicaCountTransformerSecretGeneratorValueAddTransformerHelmChartInflationGeneratorReplacementTransformer"
const _BuiltinPluginType_name = "UnknownAnnotationsTransformerConfigMapGeneratorIAMPolicyGeneratorHashTransformerImageTagTransformerLabelTransformerNamespaceTransformerPatchJson6902TransformerPatchStrategicMergeTransformerPatchTransformerPrefixSuffixTransformerPrefixTransformerSuffixTransformerReplicaCountTransformerSecretGeneratorValueAddTransformerHelmChartInflationGeneratorReplacementTransformer"
var _BuiltinPluginType_index = [...]uint16{0, 7, 29, 47, 65, 80, 99, 115, 137, 157, 181, 211, 227, 250, 267, 284, 307, 322, 341, 368, 390}
var _BuiltinPluginType_index = [...]uint16{0, 7, 29, 47, 65, 80, 99, 115, 135, 159, 189, 205, 228, 245, 262, 285, 300, 319, 346, 368}
func (i BuiltinPluginType) String() string {
if i < 0 || i >= BuiltinPluginType(len(_BuiltinPluginType_index)-1) {

View File

@@ -19,7 +19,6 @@ const (
HashTransformer
ImageTagTransformer
LabelTransformer
LegacyOrderTransformer
NamespaceTransformer
PatchJson6902Transformer
PatchStrategicMergeTransformer
@@ -100,7 +99,6 @@ var TransformerFactories = map[BuiltinPluginType]func() resmap.TransformerPlugin
HashTransformer: builtins.NewHashTransformerPlugin,
ImageTagTransformer: builtins.NewImageTagTransformerPlugin,
LabelTransformer: builtins.NewLabelTransformerPlugin,
LegacyOrderTransformer: builtins.NewLegacyOrderTransformerPlugin,
NamespaceTransformer: builtins.NewNamespaceTransformerPlugin,
PatchJson6902Transformer: builtins.NewPatchJson6902TransformerPlugin,
PatchStrategicMergeTransformer: builtins.NewPatchStrategicMergeTransformerPlugin,
@@ -111,4 +109,7 @@ var TransformerFactories = map[BuiltinPluginType]func() resmap.TransformerPlugin
ReplacementTransformer: builtins.NewReplacementTransformerPlugin,
ReplicaCountTransformer: builtins.NewReplicaCountTransformerPlugin,
ValueAddTransformer: builtins.NewValueAddTransformerPlugin,
// Do not wired SortOrderTransformer as a builtin plugin.
// We only want it to be available in the top-level kustomization.
// See: https://github.com/kubernetes-sigs/kustomize/issues/3913
}

Some files were not shown because too many files have changed in this diff Show More