├── CONTRIBUTING.md
├── LICENSE
├── LICENSE_TEMPLATE
├── Makefile
├── OWNERS
├── OWNERS_ALIASES
├── README.md
├── RELEASING.md
├── SECURITY.md
├── SECURITY_CONTACTS
├── code-of-conduct.md
├── krm-functions
├── Makefile
├── README.md
├── scripts
│ ├── build-local.sh
│ └── unit-test.sh
└── sig-cli
│ ├── OWNERS
│ ├── README.md
│ └── render-helm-chart
│ ├── Dockerfile
│ ├── README.md
│ ├── examples
│ ├── render-helm-chart-kustomize-inline-values
│ │ ├── .expected
│ │ │ ├── diff.patch
│ │ │ └── exec.sh
│ │ ├── README.md
│ │ └── kustomization.yaml
│ └── render-helm-chart-kustomize-values-files
│ │ ├── .expected
│ │ ├── diff.patch
│ │ └── exec.sh
│ │ ├── .krmignore
│ │ ├── README.md
│ │ └── kustomization.yaml
│ ├── go.mod
│ ├── go.sum
│ ├── main.go
│ ├── main_test.go
│ └── third_party
│ ├── README.md
│ └── sigs.k8s.io
│ └── kustomize
│ └── api
│ ├── builtins
│ └── HelmChartInflationGenerator.go
│ └── types
│ └── helmchartargs.go
├── publishers
├── README.md
└── sig-cli
│ ├── OWNERS
│ ├── README.md
│ ├── catalogs
│ └── v20220225.yaml
│ └── functions
│ └── render-helm-chart.yaml
├── site
└── README.md
├── test.sh
└── tests
├── e2e_test.go
├── go.mod
├── go.sum
├── testutils.go
└── validate-metadata_test.go
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing Guidelines
2 |
3 | Welcome to Kubernetes. We are excited about the prospect of you joining our [community](https://git.k8s.io/community)! The Kubernetes community abides by the CNCF [code of conduct](code-of-conduct.md). Here is an excerpt:
4 |
5 | _As contributors and maintainers of this project, and in the interest of fostering an open and welcoming community, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities._
6 |
7 | ## Getting Started
8 |
9 | ### Repo layout
10 |
11 | ```
12 | ├── publishers # Home for all functions metadata
13 | │ ├── kustomize
14 | │ │ ├── functions
15 | │ │ │ ├── fn-foo.yaml
16 | │ │ │ ├── fn-bar.yaml
17 | │ │ │ └── README.md
18 | │ │ ├── catalogs
19 | │ │ │ ├── v20220225.yaml
20 | │ │ │ ├── v20220101.yaml
21 | │ │ │ └── README.md
22 | │ │ └── OWNERS # OWNERS of the publisher
23 | │ ├── kubeflow
24 | │ ├── sig-cli
25 | │ └── OWNERS # OWNERS to approve new publishers
26 | ├── krm-functions # Home for in-tree functions source code
27 | │ ├── Makefile
28 | │ ├── kustomize
29 | │ │ ├── fn-foo
30 | │ │ ├── README.md
31 | │ │ └── OWNERS # OWNERS to approve code change to the function
32 | │ └── sig-cli
33 | ├── site
34 | ├── Makefile
35 | └── OWNERS
36 | ```
37 |
38 | ## Contributing in-tree KRM function source code
39 |
40 | To contribute KRM function source code, so that it can be managed and released by this repo, follow the instructions
41 | in the [krm-functions directory]((https://github.com/kubernetes-sigs/krm-functions-registry/tree/main/krm-functions))
42 |
43 |
44 | ## Publishing KRM function metadata in-tree and out-of-tree functions
45 |
46 | To publish KRM function metadata, independently of where the source code lives, follow the instructions
47 | in the [publishers directory](https://github.com/kubernetes-sigs/krm-functions-registry/tree/main/publishers).
48 |
49 | ## General Kubernetes Contributing docs
50 |
51 | We have full documentation on how to get started contributing here:
52 |
53 | - [Contributor License Agreement](https://git.k8s.io/community/CLA.md) Kubernetes projects require that you sign a Contributor License Agreement (CLA) before we can accept your pull requests
54 | - [Kubernetes Contributor Guide](https://git.k8s.io/community/contributors/guide) - Main contributor documentation, or you can just jump directly to the [contributing section](https://git.k8s.io/community/contributors/guide#contributing)
55 | - [Contributor Cheat Sheet](https://git.k8s.io/community/contributors/guide/contributor-cheatsheet) - Common resources for existing developers
56 |
57 | ## Mentorship
58 |
59 | - [Mentoring Initiatives](https://git.k8s.io/community/mentoring) - We have a diverse set of mentorship programs available that are always looking for volunteers!
60 |
61 | [Catalog KEP]: https://github.com/kubernetes/enhancements/tree/master/keps/sig-cli/2906-kustomize-function-catalog#function-metadata-schema
62 |
63 | ## Contact Information
64 | - [Slack channel](https://kubernetes.slack.com/messages/sig-cli-krm-functions)
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "{}"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright {yyyy} {name of copyright owner}
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/LICENSE_TEMPLATE:
--------------------------------------------------------------------------------
1 | Copyright {{.Year}} {{.Holder}}
2 |
3 | Licensed under the Apache License, Version 2.0 (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License at
6 |
7 | http://www.apache.org/licenses/LICENSE-2.0
8 |
9 | Unless required by applicable law or agreed to in writing, software
10 | distributed under the License is distributed on an "AS IS" BASIS,
11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | See the License for the specific language governing permissions and
13 | limitations under the License.
14 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | # Copyright 2022 The Kubernetes Authors.
2 | # SPDX-License-Identifier: Apache-2.0
3 | #
4 | # Makefile for KRM functions registry.
5 |
6 | MYGOBIN = $(shell go env GOBIN)
7 | ifeq ($(MYGOBIN),)
8 | MYGOBIN = $(shell go env GOPATH)/bin
9 | endif
10 | export PATH := $(MYGOBIN):$(PATH)
11 |
12 | # Run all tests in this repo for in-tree and out-of-tree functions
13 | all: install-tools license validate-metadata test-in-tree
14 |
15 | ## Run all unit tests and e2e tests for in-tree functions
16 | test-in-tree: e2e-test unit-test lint
17 |
18 | # Run all the e2e tests for in-tree functions
19 | e2e-test: build-local $(MYGOBIN)/kustomize
20 | cd tests; \
21 | go test -v -run TestExamples
22 |
23 | # Validate the metadata for all published functions
24 | validate-metadata:
25 | cd tests; \
26 | go test -v -run TestValidateMetadata
27 |
28 | # Run all unit tests for in-tree functions
29 | unit-test:
30 | cd krm-functions && $(MAKE) unit-test
31 |
32 | # Build all in-tree functions locally
33 | build-local:
34 | cd krm-functions && $(MAKE) build-local
35 |
36 | # Add project licenses to all code files in here
37 | .PHONY: license
38 | license: $(MYGOBIN)/addlicense
39 | ( find . -type f -exec bash -c "$(MYGOBIN)/addlicense -y 2022 -c 'The Kubernetes Authors.' -f LICENSE_TEMPLATE {}" ";" )
40 |
41 | # Lint all in-tree functions
42 | lint:
43 | cd tests; golangci-lint run ./...
44 | cd krm-functions && find . -type f -name go.mod -execdir golangci-lint run ./... \;
45 |
46 | # Install tools needed to run tests
47 | install-tools: \
48 | install-kustomize \
49 | install-addlicense \
50 | install-golangci-lint \
51 | install-helm
52 |
53 | # Install kustomize
54 | install-kustomize:
55 | ifeq (, $(shell which kustomize))
56 | curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash; \
57 | mv ./kustomize $(MYGOBIN)/kustomize
58 | endif
59 |
60 | # Install the addlicense tool
61 | install-addlicense:
62 | go install github.com/google/addlicense@v1.0.0
63 |
64 | # Install the lint tool
65 | install-golangci-lint:
66 | go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.44.0
67 |
68 | # Install helm v3 (needed for sig-cli/render-helm-chart)
69 | install-helm:
70 | ifeq (, $(shell which helm))
71 | curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
72 | endif
73 |
--------------------------------------------------------------------------------
/OWNERS:
--------------------------------------------------------------------------------
1 | # See the OWNERS docs at https://go.k8s.io/owners
2 |
3 | approvers:
4 | - krm-functions-registry-owners
5 | - krm-functions-registry-maintainers
6 |
--------------------------------------------------------------------------------
/OWNERS_ALIASES:
--------------------------------------------------------------------------------
1 | # See the OWNERS docs at https://go.k8s.io/owners#owners_aliases
2 |
3 | aliases:
4 | krm-functions-registry-owners:
5 | - jeremyrickard
6 | - KnVerey
7 | - mengqiy
8 |
9 | krm-functions-registry-maintainers:
10 | - natasha41575
11 |
12 | sig-cli-functions-approvers:
13 | - jeremyrickard
14 | - KnVerey
15 | - mengqiy
16 | - natasha41575
17 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # krm-functions-registry
2 |
3 | Public registry of KRM functions. This repo hosts a centralized index for KRM
4 | functions and donated source code for some KRM functions.
5 |
6 | ## Background, contributing, and releasing
7 |
8 | [KEP]
9 |
10 | [Open an Issue]
11 |
12 | [Contributor Guide]
13 |
14 | [Release Process]
15 |
16 | ## Community, discussion, contribution, and support
17 |
18 | Learn how to engage with the Kubernetes community on the [community page](http://kubernetes.io/community/).
19 |
20 | You can reach the maintainers of this project at:
21 |
22 | - [Slack](http://slack.k8s.io/)
23 | - [Mailing List](https://groups.google.com/forum/#!forum/kubernetes-dev)
24 |
25 | ### Code of conduct
26 |
27 | Participation in the Kubernetes community is governed by the [Kubernetes Code of Conduct](code-of-conduct.md).
28 |
29 | [KEP]: https://github.com/kubernetes/enhancements/tree/master/keps/sig-cli/2985-public-krm-functions-registry
30 | [Contributor Guide]: CONTRIBUTING.md
31 | [Release Process]: RELEASING.md
32 | [Open an Issue]: https://github.com/kubernetes-sigs/krm-functions-registry/issues
33 |
34 | [owners]: https://git.k8s.io/community/contributors/guide/owners.md
35 | [Creative Commons 4.0]: https://git.k8s.io/website/LICENSE
36 |
--------------------------------------------------------------------------------
/RELEASING.md:
--------------------------------------------------------------------------------
1 | # Release Process \[TODO\]
2 |
3 | This doc will cover the release process for the in-tree KRM
4 | functions whose source code is stored here.
5 |
6 |
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 | # Security Policy
2 |
3 | ## Security Announcements
4 |
5 | Join the [kubernetes-security-announce] group for security and vulnerability announcements.
6 |
7 | You can also subscribe to an RSS feed of the above using [this link][kubernetes-security-announce-rss].
8 |
9 | ## Reporting a Vulnerability
10 |
11 | Instructions for reporting a vulnerability can be found on the
12 | [Kubernetes Security and Disclosure Information] page.
13 |
14 | ## Supported Versions
15 |
16 | Information about supported Kubernetes versions can be found on the
17 | [Kubernetes version and version skew support policy] page on the Kubernetes website.
18 |
19 | [kubernetes-security-announce]: https://groups.google.com/forum/#!forum/kubernetes-security-announce
20 | [kubernetes-security-announce-rss]: https://groups.google.com/forum/feed/kubernetes-security-announce/msgs/rss_v2_0.xml?num=50
21 | [Kubernetes version and version skew support policy]: https://kubernetes.io/docs/setup/release/version-skew-policy/#supported-versions
22 | [Kubernetes Security and Disclosure Information]: https://kubernetes.io/docs/reference/issues-security/security/#report-a-vulnerability
23 |
--------------------------------------------------------------------------------
/SECURITY_CONTACTS:
--------------------------------------------------------------------------------
1 | # Defined below are the security contacts for this repo.
2 | #
3 | # They are the contact point for the Product Security Committee to reach out
4 | # to for triaging and handling of incoming issues.
5 | #
6 | # The below names agree to abide by the
7 | # [Embargo Policy](https://git.k8s.io/security/private-distributors-list.md#embargo-policy)
8 | # and will be removed and replaced if they violate that agreement.
9 | #
10 | # DO NOT REPORT SECURITY VULNERABILITIES DIRECTLY TO THESE NAMES, FOLLOW THE
11 | # INSTRUCTIONS AT https://kubernetes.io/security/
12 |
13 | jeremyrickard
14 | KnVerey
15 | mengqiy
16 |
--------------------------------------------------------------------------------
/code-of-conduct.md:
--------------------------------------------------------------------------------
1 | # Kubernetes Community Code of Conduct
2 |
3 | Please refer to our [Kubernetes Community Code of Conduct](https://git.k8s.io/community/code-of-conduct.md)
4 |
--------------------------------------------------------------------------------
/krm-functions/Makefile:
--------------------------------------------------------------------------------
1 | # Copyright 2022 The Kubernetes Authors.
2 | # SPDX-License-Identifier: Apache-2.0
3 | #
4 | # Makefile for in-tree functions.
5 |
6 | # Build all in-tree functions locally if function name not provided
7 | # Otherwise, just build that function locally.
8 | build-local:
9 | ./scripts/build-local.sh $(FUNCTION_NAME)
10 |
11 | # Run all unit tests for in-tree functions
12 | unit-test:
13 | ./scripts/unit-test.sh
14 |
--------------------------------------------------------------------------------
/krm-functions/README.md:
--------------------------------------------------------------------------------
1 | # KRM Functions
2 |
3 | This directory is the home for the source code for all in-tree functions that are maintained and
4 | released by this repository.
5 |
6 | ## Requirements
7 |
8 | By donating a function's source code to this repo, you are donating the function to SIG-CLI. We cannot
9 | accept 3rd party functions as in-tree functions.
10 |
11 | ## Files
12 |
13 | Each publisher will need to create their own subdirectory `krm-functions/{PUBLISHER}/`
14 | in this directory to store their functions source code, under . For example, SIG-CLI sponsored functions are located
15 | under `krm-functions/sig-cli/`.
16 |
17 | Each function must be in its own subdirectory `krm-functions/{PUBLISHER}/{FUNCTION NAME}/`. This directory should
18 | contain:
19 | - An OWNERS file to approve code changes to the function.
20 | - A README.md file to provide a user guide for the function.
21 | - Source code and unit tests.
22 | - A Dockerfile that describes how to build the function image.
23 | - An `examples/` directory. An `examples/` directory. Examples that will serve both as examples for functions and as e2e tests. Each example should have its
24 | own subdirectory `krm-functions/{PUBLISHER}/{FUNCTION NAME}/examples/{EXAMPLE_NAME}/`, and this directory should contain:
25 | - A README.md file that serves as a guide for the example.
26 | - A subdirectory `.expected`. This should contain two files:
27 | - `exec.sh`: A script that will run your example. This script will be run on the example directory it is in. This can
28 | be something as simple as `kustomize build --enable-alpha-plugins > resources.yaml`.
29 | - `diff.patch`: This file should contain the expected diff between the original example directory files and the files
30 | after `exec.sh` is run.
31 | - Any additional files needed for your examples to run. For example, if you are running `kustomize build` in your `exec.sh`
32 | script, you will need a kustomization file.
33 |
34 | An example of this is SIG-CLI's [render-helm-chart](https://github.com/kubernetes-sigs/krm-functions-registry/tree/main/krm-functions/sig-cli/render-helm-chart)
35 | function.
36 |
--------------------------------------------------------------------------------
/krm-functions/scripts/build-local.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 | #
3 | # Copyright 2022 The Kubernetes Authors
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | function build_image {
18 | registry="us.gcr.io/k8s-artifacts-prod/krm-functions"
19 | fn_name=`basename "${1}"`
20 | docker build -t "${registry}/${fn_name}:unstable" -f "${1}"/Dockerfile "${1}"
21 | }
22 |
23 | for d in */ ; do
24 | if [ $d != "scripts/" ]; then
25 | for e in "$d"*/ ; do
26 | fn_name=`basename "${e}"`
27 | if [ $fn_name = $1 ] || [ -z "${1}" ]; then
28 | echo building function $fn_name...
29 | build_image "${e::${#e}-1}"
30 | fi
31 | done
32 | fi
33 | done
34 |
--------------------------------------------------------------------------------
/krm-functions/scripts/unit-test.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Copyright 2022 The Kubernetes Authors.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | set -e
18 |
19 | for d in */ ; do
20 | if [ $d != "scripts/" ]; then
21 | for e in "$d"*/ ; do (
22 | echo running unit tests for "$e" ...
23 | cd "$e"
24 | go test -cover -v ./...
25 | )
26 | done
27 | fi
28 | done
29 |
--------------------------------------------------------------------------------
/krm-functions/sig-cli/OWNERS:
--------------------------------------------------------------------------------
1 | # See the OWNERS docs at https://go.k8s.io/owners
2 |
3 | approvers:
4 | - sig-cli-functions-approvers
5 |
--------------------------------------------------------------------------------
/krm-functions/sig-cli/README.md:
--------------------------------------------------------------------------------
1 | # KRM functions - SIG CLI
2 |
3 | This directory contains in-tree SIG-CLI sponsored and authored KRM functions.
--------------------------------------------------------------------------------
/krm-functions/sig-cli/render-helm-chart/Dockerfile:
--------------------------------------------------------------------------------
1 | # Copyright 2022 The Kubernetes Authors.
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | FROM golang:1.17-alpine3.13
16 | ENV CGO_ENABLED=0
17 | WORKDIR /go/src/
18 |
19 | COPY go.mod go.sum ./
20 | RUN go mod download
21 | RUN go mod tidy
22 |
23 | COPY . .
24 | RUN go build -o /usr/local/bin/function ./
25 |
26 | RUN apk update && apk add --no-cache curl
27 | ARG HELM_VERSION="v3.8.0"
28 | RUN curl -fsSL -o /helm-${HELM_VERSION}-linux-amd64.tar.gz https://get.helm.sh/helm-${HELM_VERSION}-linux-amd64.tar.gz && \
29 | tar -zxvf /helm-${HELM_VERSION}-linux-amd64.tar.gz && \
30 | mv ./linux-amd64/helm /usr/local/bin/helm
31 |
32 | #############################################
33 |
34 | FROM alpine:3.13
35 | COPY --from=0 /usr/local/bin/function /usr/local/bin/function
36 | COPY --from=0 /usr/local/bin/helm /usr/local/bin/helm
37 |
38 | ENV PATH /usr/local/bin:$PATH
39 | ENV HELM_PATH_CACHE /var/cache
40 | ENV HELM_CONFIG_HOME /tmp/helm/config
41 | ENV HELM_CACHE_HOME /tmp/helm/cache
42 |
43 | ENTRYPOINT ["function"]
--------------------------------------------------------------------------------
/krm-functions/sig-cli/render-helm-chart/README.md:
--------------------------------------------------------------------------------
1 | # render-helm-chart
2 |
3 | ## Overview
4 |
5 |
6 |
7 | The `render-helm-chart` function renders a local or remote Helm chart.
8 |
9 |
10 |
11 | Helm is a package manager for kubernetes that uses a packaging format
12 | called charts. A chart is a collection of files within a directory, which
13 | contain templates, CRDs, values, and metadata.
14 |
15 | This function renders charts by using the [helm template command],
16 | so that helm charts can be rendered without needing to install the
17 | helm binary directly.
18 |
19 | You can learn more about helm [here][helm] and more about helm
20 | charts [here][charts].
21 |
22 | ## Usage
23 |
24 | This function can be used with any KRM function orchestrators such to render a specified helm chart.
25 | To run the function with kustomize, the `network` field is needed for remote charts and the `mounts`
26 | field is needed for local charts.
27 |
28 | ### FunctionConfig
29 |
30 | There are 2 kinds of `functionConfig` supported by this function:
31 |
32 | - `ConfigMap`
33 | - A custom resource of kind `RenderHelmChart`
34 |
35 | Many of the fields in each functionConfig map directly to flag options provided by `helm template`.
36 |
37 | #### `ConfigMap`
38 | To use a `ConfigMap` as the `functionConfig`, the desired parameters must be
39 | specified in the `data` field:
40 |
41 | ```yaml
42 | data:
43 | chartHome: string
44 | configHome: string
45 | name: string
46 | version: string
47 | repo: string
48 | releaseName: string
49 | namespace: string
50 | nameTemplate: string
51 | includeCRDs: string
52 | skipTests: string
53 | valuesFile: string
54 | ```
55 |
56 |
57 | | Field | Description | Example
58 | | -----------: | ----------- | -----------
59 | `chartHome` | A filepath to a directory of charts. The function will look for the chart in this local directory before attempting to pull the chart from a specified repo. Defaults to "tmp/charts". When run in a container, this path MUST have the prefix "tmp/". | tmp/charts
60 | `configHome` | Defines a value that the function should pass to helm via the HELM_CONFIG_HOME environment variable. If omitted, {tmpDir}/helm is used, where {tmpDir} is some temporary directory created by the function for the benefit of helm. This option is not supported when running in a container. It is supported only in exec mode (e.g. with kustomize) | /tmp/helm/config
61 | `name` | The name of the chart | minecraft
62 | `version` | The version of the chart | 3.1.3
63 | `repo` | A URL locating the chart on the internet | https://itzg.github.io/minecraft-server-charts
64 | `releaseName` | Replaces RELEASE_NAME in the chart template output | test
65 | `namespace` | Sets the target namespace for a release (`.Release.Namespace` in the template) | my-namespace
66 | `nameTemplate` | Specify the template used to name the release | gatekeeper
67 | `includeCRDs` | Specifies if Helm should also generate CustomResourceDefinitions. Legal values: "true", "false" (default). | "true"
68 | `skipTests` | If set, skip tests from templated output. Legal values: "true", "false" (default). | "true"
69 | `valuesFile` | valuesFile is a remote or local file path to a values file to use instead of the default values that accompanied the chart. The default values are in '{chartHome}/{name}/values.yaml', where `chartHome` and `name` are the parameters defined above. | Using a local values file: path/to/your/values.yaml
Using a remote values file: https://raw.githubusercontent.com/config-sync-examples/helm-components/main/cert-manager-values.yaml
70 |
71 |
72 | #### `RenderHelmChart`
73 | A `functionConfig` of kind `RenderHelmChart` has the following supported parameters:
74 |
75 | ```yaml
76 | helmGlobals:
77 | chartHome: string
78 | configHome: string
79 | helmCharts:
80 | - chartArgs:
81 | name: string
82 | version: string
83 | repo: string
84 | templateOptions:
85 | apiVersions: []string
86 | releaseName: string
87 | namespace: string
88 | nameTemplate: string
89 | includeCRDs: bool
90 | skipTests: bool
91 | values:
92 | valuesFiles: []string
93 | valuesInline: map[string]interface{}
94 | valuesMerge: string
95 | ```
96 |
97 | | Field | Description | Example
98 | | -----------: | ----------- | -----------
99 | `helmGlobals` | Parameters applied to all Helm charts
100 | `helmCharts` | An array of helm chart parameters
101 | `chartArgs` | Arguments that describe the chart being rendered.
102 | `templateOptions` | A collection of fields that map to flag options of `helm template`.
103 | `chartHome` | A filepath to a directory of charts. The function will look for the chart in this local directory before attempting to pull the chart from a specified repo. Defaults to "tmp/charts". When run in a container, this path MUST have the prefix "tmp/". | tmp/charts
104 | `configHome` | Defines a value that the function should pass to helm via the HELM_CONFIG_HOME environment variable. If omitted, {tmpDir}/helm is used, where {tmpDir} is some temporary directory created by the function for the benefit of helm. This option is not supported when running in a container. It is supported only in exec mode (e.g. with kustomize) | /tmp/helm/config
105 | `name` | The name of the chart | minecraft
106 | `version` | The version of the chart | 3.1.3
107 | `repo` | A URL locating the chart on the internet | https://itzg.github.io/minecraft-server-charts
108 | `apiVersions` | Kubernetes api versions used for Capabilities.APIVersions | acme.cert-manager.io/v1
109 | `releaseName` | Replaces RELEASE_NAME in the chart template output | test
110 | `namespace` | Sets the target namespace for a release (`.Release.Namespace` in the template) | my-namespace
111 | `nameTemplate` | Specify the template used to name the release | gatekeeper
112 | `includeCRDs` | Specifies if Helm should also generate CustomResourceDefinitions. Legal values: "true", "false" (default). | "true"
113 | `skipTests` | If set, skip tests from templated output. Legal values: "true", "false" (default). | "true"
114 | `values` | Values to use instead of the default values that accompany the chart. This can be defined inline or in a file.
115 | `valuesInline` | Values defined inline to use instead of default values that accompany the chart | global:
enabled: false
tests:
enabled: false
116 | `valuesFiles` | Remote or local filepaths to use instead of the default values that accompanied the chart. The default values are in '{chartHome}/{name}/values.yaml', where `chartHome` and `name` are the parameters defined above. | Using a local values file: path/to/your/values.yaml
Using a remote values file: https://raw.githubusercontent.com/config-sync-examples/helm-components/main/cert-manager-values.yaml
117 | `valuesMerge` | ValuesMerge specifies how to treat ValuesInline with respect to ValuesFiles. Legal values: 'merge', 'override' (default), 'replace'. | replace
118 |
119 | [helm]: https://helm.sh/
120 | [charts]: https://helm.sh/docs/topics/charts/
121 | [helm template command]: https://helm.sh/docs/helm/helm_template/
122 |
--------------------------------------------------------------------------------
/krm-functions/sig-cli/render-helm-chart/examples/render-helm-chart-kustomize-inline-values/.expected/diff.patch:
--------------------------------------------------------------------------------
1 | diff --git a/resources.yaml b/resources.yaml
2 | new file mode 100644
3 | index 0000000..e2e869b
4 | --- /dev/null
5 | +++ b/resources.yaml
6 | @@ -0,0 +1,127 @@
7 | +apiVersion: rbac.authorization.k8s.io/v1
8 | +kind: Role
9 | +metadata:
10 | + name: moria-ocp-pipeline
11 | + namespace: mynamespace
12 | +rules:
13 | +- apiGroups:
14 | + - ""
15 | + resources:
16 | + - '*'
17 | + verbs:
18 | + - '*'
19 | +---
20 | +apiVersion: rbac.authorization.k8s.io/v1
21 | +kind: RoleBinding
22 | +metadata:
23 | + name: moria-ocp-pipeline
24 | + namespace: mynamespace
25 | +roleRef:
26 | + apiGroup: rbac.authorization.k8s.io
27 | + kind: Role
28 | + name: moria-ocp-pipeline
29 | +subjects:
30 | +- kind: ServiceAccount
31 | + name: jenkins
32 | + namespace: mynamespace
33 | +---
34 | +apiVersion: v1
35 | +data:
36 | + config: eyJleGFtcGxlIjoidmFsdWUifQ==
37 | +kind: Secret
38 | +metadata:
39 | + labels:
40 | + chart: ocp-pipeline-0.1.16
41 | + heritage: Helm
42 | + release: moria
43 | + name: moria-config
44 | +type: Opaque
45 | +---
46 | +apiVersion: v1
47 | +data:
48 | + WebHookSecretKey: MTIzNDU2Nzg=
49 | +kind: Secret
50 | +metadata:
51 | + labels:
52 | + chart: ocp-pipeline-0.1.16
53 | + heritage: Helm
54 | + release: moria
55 | + name: moria-git-webhook-secret
56 | +type: Opaque
57 | +---
58 | +apiVersion: build.openshift.io/v1
59 | +kind: BuildConfig
60 | +metadata:
61 | + labels:
62 | + app: ocp-pipeline
63 | + chart: ocp-pipeline-0.1.16
64 | + heritage: Helm
65 | + release: moria
66 | + name: moria-ocp-pipeline-deploy
67 | + namespace: null
68 | +spec:
69 | + nodeSelector: {}
70 | + resources:
71 | + limits:
72 | + cpu: 4000m
73 | + memory: 8G
74 | + requests:
75 | + cpu: 2000m
76 | + memory: 4G
77 | + strategy:
78 | + jenkinsPipelineStrategy:
79 | + jenkinsfile: |-
80 | + def helmName = "helm-v3.1.0-linux-amd64.tar.gz"
81 | + def chartName = "metadata-curator"
82 | + def chartRepo = "http://bcgov.github.io/helm-charts"
83 | + def releaseName = "mc"
84 | + def releaseNamespace = ""
85 | + def forceRecreate = "false"
86 | + def callAnotherPipe = "false"
87 | + def useEnv = "false"
88 | + def fromEnv = "commit"
89 | + def setFlag = "image.tag"
90 | +
91 | + node("nodejs") {
92 | + stage("deploy (it's already built)") {
93 | + sh """
94 | + curl -L -O https://get.helm.sh/${helmName}
95 | + tar -zxvf ${helmName}
96 | + cd linux-amd64
97 | +
98 | + curl -L -O https://github.com/stedolan/jq/releases/download/jq-1.6/jq-linux32
99 | + chmod ugo+x ./jq-linux32
100 | + npm install -g json2yaml
101 | +
102 | + export CONF1=`oc get secret moria-config -o json | ./jq-linux32 .data.config`
103 | + export CONF2=`sed -e 's/^"//' -e 's/"\$//' <<<"\$CONF1"`
104 | + export CONF3=`echo \$CONF2 | base64 -d -`
105 | + export CONF=`echo \$CONF3 | json2yaml`
106 | +
107 | + echo "\$CONF" > ./config.yaml
108 | + oc project ${releaseNamespace}
109 | + ./helm repo add chart ${chartRepo}
110 | + ./helm repo update
111 | + if [ "${forceRecreate}" = "true" ]; then
112 | + ./helm upgrade ${releaseName} chart/${chartName} -f ./config.yaml --install --set hashLabel="${releaseName}\$(cat /dev/urandom | tr -dc 'a-z0-9' | fold -w 32 | head -n 1)"
113 | + elif [ "${useEnv}" = "true" ]; then
114 | + ./helm upgrade ${releaseName} chart/${chartName} -f ./config.yaml --install --set ${setFlag}=${env[fromEnv]}
115 | + else
116 | + ./helm upgrade ${releaseName} chart/${chartName} -f ./config.yaml --install
117 | + fi
118 | +
119 | + if [ "${callAnotherPipe}" = "true" ]; then
120 | + curl -d '' http://otherwebhookUrl
121 | + fi
122 | + """
123 | + }
124 | + }
125 | + type: JenkinsPipeline
126 | + triggers:
127 | + - generic:
128 | + allowEnv: true
129 | + secretReference:
130 | + name: moria-git-webhook-secret
131 | + type: generic
132 | +status:
133 | + lastVersion: 0
134 |
--------------------------------------------------------------------------------
/krm-functions/sig-cli/render-helm-chart/examples/render-helm-chart-kustomize-inline-values/.expected/exec.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # Copyright 2022 The Kubernetes Authors.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 |
16 |
17 | # kustomize 4.2.0 is preinstalled in github actions
18 | kustomize build --enable-alpha-plugins --network > resources.yaml
19 |
--------------------------------------------------------------------------------
/krm-functions/sig-cli/render-helm-chart/examples/render-helm-chart-kustomize-inline-values/README.md:
--------------------------------------------------------------------------------
1 | # render-helm-chart: Kustomize Inline Values
2 |
3 | ### Overview
4 |
5 | This example demonstrates how to declaratively invoke the `render-helm-chart`
6 | function with kustomize using the `valuesInline` field.
7 |
8 | ### Function invocation
9 |
10 | To use the function with kustomize, you can specify the `functionConfig`
11 | in your kustomization's `generators` field. This example uses inline values
12 | to use instead of the default values accompanying the chart:
13 |
14 | kustomization.yaml:
15 | ```yaml
16 | generators:
17 | - |-
18 | apiVersion: v1alpha1
19 | kind: RenderHelmChart
20 | metadata:
21 | name: demo
22 | annotations:
23 | config.kubernetes.io/function: |
24 | container:
25 | network: true
26 | image: us.gcr.io/k8s-artifacts-prod/krm-functions/render-helm-chart:unstable
27 | helmCharts:
28 | - chartArgs:
29 | name: ocp-pipeline
30 | version: 0.1.16
31 | repo: https://bcgov.github.io/helm-charts
32 | templateOptions:
33 | releaseName: moria
34 | namespace: mynamespace
35 | values:
36 | valuesInline:
37 | releaseNamespace: ""
38 | rbac:
39 | create: true
40 | rules:
41 | - apiGroups: [""]
42 | verbs: ["*"]
43 | resources: ["*"]
44 | ```
45 |
46 | Then, to build the kustomization with kustomize v4:
47 |
48 | ```shell
49 | kustomize build --enable-alpha-plugins --network .
50 | ```
51 |
52 | ### Expected result
53 |
54 | You should also be able to find the line `def releaseNamespace = ""` somewhere
55 | in your output, as well as the following:
56 |
57 | ```yaml
58 | apiVersion: rbac.authorization.k8s.io/v1
59 | kind: Role
60 | metadata:
61 | name: moria-ocp-pipeline
62 | namespace: mynamespace
63 | rules:
64 | - apiGroups:
65 | - ""
66 | resources:
67 | - '*'
68 | verbs:
69 | - '*'
70 | ---
71 | apiVersion: rbac.authorization.k8s.io/v1
72 | kind: RoleBinding
73 | metadata:
74 | name: moria-ocp-pipeline
75 | namespace: mynamespace
76 | roleRef:
77 | apiGroup: rbac.authorization.k8s.io
78 | kind: Role
79 | name: moria-ocp-pipeline
80 | subjects:
81 | - kind: ServiceAccount
82 | name: jenkins
83 | namespace: mynamespace
84 | ```
85 |
86 | which demonstrates that the correct values provided via `valuesInline` were used.
--------------------------------------------------------------------------------
/krm-functions/sig-cli/render-helm-chart/examples/render-helm-chart-kustomize-inline-values/kustomization.yaml:
--------------------------------------------------------------------------------
1 | # Copyright 2022 The Kubernetes Authors.
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | generators:
16 | - |-
17 | apiVersion: v1alpha1
18 | kind: RenderHelmChart
19 | metadata:
20 | name: demo
21 | annotations:
22 | config.kubernetes.io/function: |
23 | container:
24 | network: true
25 | image: us.gcr.io/k8s-artifacts-prod/krm-functions/render-helm-chart:unstable
26 | helmCharts:
27 | - chartArgs:
28 | name: ocp-pipeline
29 | version: 0.1.16
30 | repo: https://bcgov.github.io/helm-charts
31 | templateOptions:
32 | releaseName: moria
33 | namespace: mynamespace
34 | values:
35 | valuesInline:
36 | releaseNamespace: ""
37 | rbac:
38 | create: true
39 | rules:
40 | - apiGroups: [""]
41 | verbs: ["*"]
42 | resources: ["*"]
--------------------------------------------------------------------------------
/krm-functions/sig-cli/render-helm-chart/examples/render-helm-chart-kustomize-values-files/.expected/diff.patch:
--------------------------------------------------------------------------------
1 | diff --git a/resources.yaml b/resources.yaml
2 | new file mode 100644
3 | index 0000000..e2e869b
4 | --- /dev/null
5 | +++ b/resources.yaml
6 | @@ -0,0 +1,127 @@
7 | +apiVersion: rbac.authorization.k8s.io/v1
8 | +kind: Role
9 | +metadata:
10 | + name: moria-ocp-pipeline
11 | + namespace: mynamespace
12 | +rules:
13 | +- apiGroups:
14 | + - ""
15 | + resources:
16 | + - '*'
17 | + verbs:
18 | + - '*'
19 | +---
20 | +apiVersion: rbac.authorization.k8s.io/v1
21 | +kind: RoleBinding
22 | +metadata:
23 | + name: moria-ocp-pipeline
24 | + namespace: mynamespace
25 | +roleRef:
26 | + apiGroup: rbac.authorization.k8s.io
27 | + kind: Role
28 | + name: moria-ocp-pipeline
29 | +subjects:
30 | +- kind: ServiceAccount
31 | + name: jenkins
32 | + namespace: mynamespace
33 | +---
34 | +apiVersion: v1
35 | +data:
36 | + config: eyJleGFtcGxlIjoidmFsdWUifQ==
37 | +kind: Secret
38 | +metadata:
39 | + labels:
40 | + chart: ocp-pipeline-0.1.16
41 | + heritage: Helm
42 | + release: moria
43 | + name: moria-config
44 | +type: Opaque
45 | +---
46 | +apiVersion: v1
47 | +data:
48 | + WebHookSecretKey: MTIzNDU2Nzg=
49 | +kind: Secret
50 | +metadata:
51 | + labels:
52 | + chart: ocp-pipeline-0.1.16
53 | + heritage: Helm
54 | + release: moria
55 | + name: moria-git-webhook-secret
56 | +type: Opaque
57 | +---
58 | +apiVersion: build.openshift.io/v1
59 | +kind: BuildConfig
60 | +metadata:
61 | + labels:
62 | + app: ocp-pipeline
63 | + chart: ocp-pipeline-0.1.16
64 | + heritage: Helm
65 | + release: moria
66 | + name: moria-ocp-pipeline-deploy
67 | + namespace: null
68 | +spec:
69 | + nodeSelector: {}
70 | + resources:
71 | + limits:
72 | + cpu: 4000m
73 | + memory: 8G
74 | + requests:
75 | + cpu: 2000m
76 | + memory: 4G
77 | + strategy:
78 | + jenkinsPipelineStrategy:
79 | + jenkinsfile: |-
80 | + def helmName = "helm-v3.1.0-linux-amd64.tar.gz"
81 | + def chartName = "metadata-curator"
82 | + def chartRepo = "http://bcgov.github.io/helm-charts"
83 | + def releaseName = "mc"
84 | + def releaseNamespace = ""
85 | + def forceRecreate = "false"
86 | + def callAnotherPipe = "false"
87 | + def useEnv = "false"
88 | + def fromEnv = "commit"
89 | + def setFlag = "image.tag"
90 | +
91 | + node("nodejs") {
92 | + stage("deploy (it's already built)") {
93 | + sh """
94 | + curl -L -O https://get.helm.sh/${helmName}
95 | + tar -zxvf ${helmName}
96 | + cd linux-amd64
97 | +
98 | + curl -L -O https://github.com/stedolan/jq/releases/download/jq-1.6/jq-linux32
99 | + chmod ugo+x ./jq-linux32
100 | + npm install -g json2yaml
101 | +
102 | + export CONF1=`oc get secret moria-config -o json | ./jq-linux32 .data.config`
103 | + export CONF2=`sed -e 's/^"//' -e 's/"\$//' <<<"\$CONF1"`
104 | + export CONF3=`echo \$CONF2 | base64 -d -`
105 | + export CONF=`echo \$CONF3 | json2yaml`
106 | +
107 | + echo "\$CONF" > ./config.yaml
108 | + oc project ${releaseNamespace}
109 | + ./helm repo add chart ${chartRepo}
110 | + ./helm repo update
111 | + if [ "${forceRecreate}" = "true" ]; then
112 | + ./helm upgrade ${releaseName} chart/${chartName} -f ./config.yaml --install --set hashLabel="${releaseName}\$(cat /dev/urandom | tr -dc 'a-z0-9' | fold -w 32 | head -n 1)"
113 | + elif [ "${useEnv}" = "true" ]; then
114 | + ./helm upgrade ${releaseName} chart/${chartName} -f ./config.yaml --install --set ${setFlag}=${env[fromEnv]}
115 | + else
116 | + ./helm upgrade ${releaseName} chart/${chartName} -f ./config.yaml --install
117 | + fi
118 | +
119 | + if [ "${callAnotherPipe}" = "true" ]; then
120 | + curl -d '' http://otherwebhookUrl
121 | + fi
122 | + """
123 | + }
124 | + }
125 | + type: JenkinsPipeline
126 | + triggers:
127 | + - generic:
128 | + allowEnv: true
129 | + secretReference:
130 | + name: moria-git-webhook-secret
131 | + type: generic
132 | +status:
133 | + lastVersion: 0
134 |
--------------------------------------------------------------------------------
/krm-functions/sig-cli/render-helm-chart/examples/render-helm-chart-kustomize-values-files/.expected/exec.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | # Copyright 2022 The Kubernetes Authors.
3 | #
4 | # Licensed under the Apache License, Version 2.0 (the "License");
5 | # you may not use this file except in compliance with the License.
6 | # You may obtain a copy of the License at
7 | #
8 | # http://www.apache.org/licenses/LICENSE-2.0
9 | #
10 | # Unless required by applicable law or agreed to in writing, software
11 | # distributed under the License is distributed on an "AS IS" BASIS,
12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | # See the License for the specific language governing permissions and
14 | # limitations under the License.
15 |
16 |
17 | # kustomize 4.2.0 is preinstalled in github actions
18 | kustomize build --enable-alpha-plugins --network > resources.yaml
19 |
--------------------------------------------------------------------------------
/krm-functions/sig-cli/render-helm-chart/examples/render-helm-chart-kustomize-values-files/.krmignore:
--------------------------------------------------------------------------------
1 | .expected
2 |
--------------------------------------------------------------------------------
/krm-functions/sig-cli/render-helm-chart/examples/render-helm-chart-kustomize-values-files/README.md:
--------------------------------------------------------------------------------
1 | # render-helm-chart: Kustomize Values Files
2 |
3 | ### Overview
4 |
5 | This example demonstrates how to declaratively invoke the `render-helm-chart`
6 | function with kustomize using multiple values files.
7 |
8 | ### Function invocation
9 |
10 | To use the function with kustomize, you can specify the `functionConfig`
11 | in your kustomization's `generators` field. This example specifies multiple remote
12 | values files to use instead of the default values accompanying the chart:
13 |
14 | kustomization.yaml:
15 | ```yaml
16 | generators:
17 | - |-
18 | apiVersion: v1alpha1
19 | kind: RenderHelmChart
20 | metadata:
21 | name: demo
22 | annotations:
23 | config.kubernetes.io/function: |
24 | container:
25 | network: true
26 | image: us.gcr.io/k8s-artifacts-prod/krm-functions/render-helm-chart:unstable
27 | helmCharts:
28 | - chartArgs:
29 | name: ocp-pipeline
30 | version: 0.1.16
31 | repo: https://bcgov.github.io/helm-charts
32 | templateOptions:
33 | namespace: mynamespace
34 | releaseName: moria
35 | values:
36 | valuesFiles:
37 | - https://raw.githubusercontent.com/natasha41575/kpt-functions-catalog/a9c9cd765a05f7a7fb6923dbde4651b62c9c229c/examples/render-helm-chart-kustomize-values-files/file1.yaml
38 | - https://raw.githubusercontent.com/natasha41575/kpt-functions-catalog/a9c9cd765a05f7a7fb6923dbde4651b62c9c229c/examples/render-helm-chart-kustomize-values-files/file2.yaml
39 | ```
40 |
41 | Then, to build the kustomization with kustomize v4:
42 |
43 | ```shell
44 | kustomize build --enable-alpha-plugins --network .
45 | ```
46 |
47 | ### Expected result
48 |
49 | You should also be able to find the line `def releaseNamespace = ""` somewhere
50 | in your output, as well as the following:
51 |
52 | ```yaml
53 | apiVersion: rbac.authorization.k8s.io/v1
54 | kind: Role
55 | metadata:
56 | name: moria-ocp-pipeline
57 | namespace: mynamespace
58 | rules:
59 | - apiGroups:
60 | - ""
61 | resources:
62 | - '*'
63 | verbs:
64 | - '*'
65 | ---
66 | apiVersion: rbac.authorization.k8s.io/v1
67 | kind: RoleBinding
68 | metadata:
69 | name: moria-ocp-pipeline
70 | namespace: mynamespace
71 | roleRef:
72 | apiGroup: rbac.authorization.k8s.io
73 | kind: Role
74 | name: moria-ocp-pipeline
75 | subjects:
76 | - kind: ServiceAccount
77 | name: jenkins
78 | namespace: mynamespace
79 | ```
80 |
81 | which demonstrates that the correct values provided via `valuesFiles` were used.
--------------------------------------------------------------------------------
/krm-functions/sig-cli/render-helm-chart/examples/render-helm-chart-kustomize-values-files/kustomization.yaml:
--------------------------------------------------------------------------------
1 | # Copyright 2022 The Kubernetes Authors.
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | generators:
16 | - |-
17 | apiVersion: v1alpha1
18 | kind: RenderHelmChart
19 | metadata:
20 | name: demo
21 | annotations:
22 | config.kubernetes.io/function: |
23 | container:
24 | network: true
25 | image: us.gcr.io/k8s-artifacts-prod/krm-functions/render-helm-chart:unstable
26 | helmCharts:
27 | - chartArgs:
28 | name: ocp-pipeline
29 | version: 0.1.16
30 | repo: https://bcgov.github.io/helm-charts
31 | templateOptions:
32 | namespace: mynamespace
33 | releaseName: moria
34 | values:
35 | valuesFiles:
36 | - https://raw.githubusercontent.com/natasha41575/kpt-functions-catalog/a9c9cd765a05f7a7fb6923dbde4651b62c9c229c/examples/render-helm-chart-kustomize-values-files/file1.yaml
37 | - https://raw.githubusercontent.com/natasha41575/kpt-functions-catalog/a9c9cd765a05f7a7fb6923dbde4651b62c9c229c/examples/render-helm-chart-kustomize-values-files/file2.yaml
38 |
--------------------------------------------------------------------------------
/krm-functions/sig-cli/render-helm-chart/go.mod:
--------------------------------------------------------------------------------
1 | module sigs.k8s.io/krm-functions-registry/krm-functions/sig-cli/render-helm-chart
2 |
3 | go 1.17
4 |
5 | require (
6 | github.com/imdario/mergo v0.3.12
7 | github.com/pkg/errors v0.9.1
8 | sigs.k8s.io/kustomize/api v0.8.11
9 | sigs.k8s.io/kustomize/kyaml v0.11.0
10 | sigs.k8s.io/yaml v1.2.0
11 | )
12 |
13 | require (
14 | github.com/PuerkitoBio/purell v1.1.1 // indirect
15 | github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
16 | github.com/davecgh/go-spew v1.1.1 // indirect
17 | github.com/go-errors/errors v1.0.1 // indirect
18 | github.com/go-openapi/jsonpointer v0.19.3 // indirect
19 | github.com/go-openapi/jsonreference v0.19.3 // indirect
20 | github.com/go-openapi/swag v0.19.5 // indirect
21 | github.com/inconshreveable/mousetrap v1.0.0 // indirect
22 | github.com/mailru/easyjson v0.7.0 // indirect
23 | github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect
24 | github.com/pmezard/go-difflib v1.0.0 // indirect
25 | github.com/spf13/cobra v1.0.0 // indirect
26 | github.com/spf13/pflag v1.0.5 // indirect
27 | github.com/stretchr/testify v1.5.1 // indirect
28 | github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca // indirect
29 | golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e // indirect
30 | golang.org/x/text v0.3.2 // indirect
31 | gopkg.in/yaml.v2 v2.4.0 // indirect
32 | k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e // indirect
33 | )
34 |
--------------------------------------------------------------------------------
/krm-functions/sig-cli/render-helm-chart/go.sum:
--------------------------------------------------------------------------------
1 | cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
2 | github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
3 | github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
4 | github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
5 | github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
6 | github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
7 | github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
8 | github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
9 | github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
10 | github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
11 | github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
12 | github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
13 | github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
14 | github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
15 | github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
16 | github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
17 | github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
18 | github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
19 | github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
20 | github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
21 | github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
22 | github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
23 | github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
24 | github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
25 | github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
26 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
27 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
28 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
29 | github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
30 | github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
31 | github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
32 | github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
33 | github.com/evanphx/json-patch v4.11.0+incompatible h1:glyUF9yIYtMHzn8xaKw5rMhdWcwsYV8dZHIq5567/xs=
34 | github.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
35 | github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
36 | github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
37 | github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w=
38 | github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
39 | github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
40 | github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
41 | github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
42 | github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
43 | github.com/go-openapi/jsonpointer v0.19.3 h1:gihV7YNZK1iK6Tgwwsxo2rJbD1GTbdm72325Bq8FI3w=
44 | github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
45 | github.com/go-openapi/jsonreference v0.19.3 h1:5cxNfTy0UVC3X8JL5ymxzyoUZmo8iZb+jeTWn7tUa8o=
46 | github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
47 | github.com/go-openapi/swag v0.19.5 h1:lTz6Ys4CmqqCQmZPBlbQENR1/GucA2bzYTE12Pw4tFY=
48 | github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
49 | github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
50 | github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
51 | github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
52 | github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
53 | github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
54 | github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
55 | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
56 | github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
57 | github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
58 | github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
59 | github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
60 | github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
61 | github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
62 | github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
63 | github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
64 | github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
65 | github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
66 | github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
67 | github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
68 | github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
69 | github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
70 | github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
71 | github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
72 | github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
73 | github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU=
74 | github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
75 | github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
76 | github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
77 | github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
78 | github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
79 | github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
80 | github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
81 | github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
82 | github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
83 | github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
84 | github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
85 | github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
86 | github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
87 | github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
88 | github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
89 | github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
90 | github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
91 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
92 | github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs=
93 | github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
94 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
95 | github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
96 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
97 | github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
98 | github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
99 | github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
100 | github.com/mailru/easyjson v0.7.0 h1:aizVhC/NAAcKWb+5QsU1iNOZb4Yws5UO2I+aIprQITM=
101 | github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
102 | github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
103 | github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
104 | github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
105 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
106 | github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
107 | github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0=
108 | github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4=
109 | github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
110 | github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
111 | github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
112 | github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
113 | github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
114 | github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
115 | github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
116 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
117 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
118 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
119 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
120 | github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
121 | github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
122 | github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
123 | github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
124 | github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
125 | github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
126 | github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
127 | github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
128 | github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
129 | github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
130 | github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
131 | github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
132 | github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
133 | github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
134 | github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
135 | github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
136 | github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
137 | github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
138 | github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
139 | github.com/spf13/cobra v1.0.0 h1:6m/oheQuQ13N9ks4hubMG6BnvwOeaJrqSPLahSnczz8=
140 | github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
141 | github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
142 | github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
143 | github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
144 | github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
145 | github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
146 | github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
147 | github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
148 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
149 | github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
150 | github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48=
151 | github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
152 | github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
153 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
154 | github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
155 | github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
156 | github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
157 | github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
158 | github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
159 | github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
160 | github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca h1:1CFlNzQhALwjS9mBAUkycX616GzgsuYUOCHA5+HSlXI=
161 | github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg=
162 | github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
163 | go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
164 | go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 h1:+FNtrFTmVw0YZGpBGX56XDee331t6JAXeK2bcyhLOOc=
165 | go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o=
166 | go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
167 | go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
168 | go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
169 | golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
170 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
171 | golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
172 | golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
173 | golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
174 | golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
175 | golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
176 | golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
177 | golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
178 | golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
179 | golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e h1:3G+cUijn7XD+S4eJFddp53Pv7+slrESplyjG25HgL+k=
180 | golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
181 | golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
182 | golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
183 | golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
184 | golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
185 | golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
186 | golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
187 | golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
188 | golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
189 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
190 | golang.org/x/sys v0.0.0-20191002063906-3421d5a6bb1c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
191 | golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
192 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
193 | golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
194 | golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
195 | golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
196 | golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
197 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
198 | golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
199 | golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
200 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
201 | google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
202 | google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
203 | google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
204 | google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
205 | google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
206 | google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
207 | google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
208 | google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
209 | google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
210 | google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
211 | gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
212 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
213 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
214 | gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
215 | gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
216 | gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
217 | gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
218 | gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
219 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
220 | gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
221 | gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
222 | gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
223 | gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
224 | gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
225 | gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
226 | honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
227 | k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
228 | k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
229 | k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e h1:KLHHjkdQFomZy8+06csTWZ0m1343QqxZhR2LJ1OxCYM=
230 | k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw=
231 | sigs.k8s.io/kustomize/api v0.8.11 h1:LzQzlq6Z023b+mBtc6v72N2mSHYmN8x7ssgbf/hv0H8=
232 | sigs.k8s.io/kustomize/api v0.8.11/go.mod h1:a77Ls36JdfCWojpUqR6m60pdGY1AYFix4AH83nJtY1g=
233 | sigs.k8s.io/kustomize/kyaml v0.11.0 h1:9KhiCPKaVyuPcgOLJXkvytOvjMJLoxpjodiycb4gHsA=
234 | sigs.k8s.io/kustomize/kyaml v0.11.0/go.mod h1:GNMwjim4Ypgp/MueD3zXHLRJEjz7RvtPae0AwlvEMFM=
235 | sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
236 | sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
237 | sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
238 |
--------------------------------------------------------------------------------
/krm-functions/sig-cli/render-helm-chart/main.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021 The Kubernetes Authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package main
16 |
17 | import (
18 | "fmt"
19 | "os"
20 |
21 | "sigs.k8s.io/krm-functions-registry/krm-functions/sig-cli/render-helm-chart/third_party/sigs.k8s.io/kustomize/api/builtins"
22 | "sigs.k8s.io/kustomize/api/resmap"
23 | "sigs.k8s.io/kustomize/api/resource"
24 | "sigs.k8s.io/kustomize/kyaml/fn/framework"
25 | "sigs.k8s.io/kustomize/kyaml/fn/framework/command"
26 | kyaml "sigs.k8s.io/kustomize/kyaml/yaml"
27 | )
28 |
29 | const (
30 | fnConfigKind = "RenderHelmChart"
31 | configMap = "ConfigMap"
32 | )
33 |
34 | //nolint
35 | func main() {
36 | asp := HelmChartProcessor{}
37 | cmd := command.Build(&asp, command.StandaloneEnabled, false)
38 | if err := cmd.Execute(); err != nil {
39 | os.Exit(1)
40 | }
41 | }
42 |
43 | type HelmChartProcessor struct{}
44 |
45 | func (slp *HelmChartProcessor) Process(resourceList *framework.ResourceList) error {
46 | err := run(resourceList)
47 | if err != nil {
48 | resourceList.Result = &framework.Result{
49 | Name: "render-helm-chart",
50 | Items: []framework.ResultItem{
51 | {
52 | Message: err.Error(),
53 | Severity: framework.Error,
54 | },
55 | },
56 | }
57 | return resourceList.Result
58 | }
59 | return nil
60 | }
61 |
62 | type helmChartInflatorFunction struct {
63 | kyaml.ResourceMeta `json:",inline" yaml:",inline"`
64 | plugins []builtins.HelmChartInflationGeneratorPlugin
65 | }
66 |
67 | func (f *helmChartInflatorFunction) Config(rn *kyaml.RNode) error {
68 | y, err := rn.String()
69 | if err != nil {
70 | return fmt.Errorf("cannot get YAML from RNode: %w", err)
71 | }
72 | kind, err := f.getKind(rn)
73 | if err != nil {
74 | return err
75 | }
76 | switch kind {
77 | case fnConfigKind:
78 | err = f.RenderHelmChartArgs([]byte(y))
79 | if err != nil {
80 | return err
81 | }
82 | case configMap:
83 | dataMap := rn.GetDataMap()
84 | bytes, err := kyaml.Marshal(dataMap)
85 | if err != nil {
86 | return err
87 | }
88 | err = f.ConfigMapArgs(bytes)
89 | if err != nil {
90 | return err
91 | }
92 | default:
93 | return fmt.Errorf("`functionConfig` must be `%s` or `%s`", configMap, fnConfigKind)
94 | }
95 | return nil
96 | }
97 |
98 | func (f *helmChartInflatorFunction) Run(items []*kyaml.RNode) ([]*kyaml.RNode, error) {
99 | resmapFactory := builtins.NewResMapFactory()
100 | resMap, err := resmapFactory.NewResMapFromRNodeSlice(items)
101 | if err != nil {
102 | return nil, err
103 | }
104 | var rm resmap.ResMap
105 | for _, p := range f.plugins {
106 | rm, err = p.Generate()
107 | if err != nil {
108 | return nil, fmt.Errorf("failed to run generator: %w", err)
109 | }
110 |
111 | // check for duplicates for idempotency
112 | for i := range items {
113 | resources := rm.Resources()
114 | for r := range resources {
115 | it := &resource.Resource{RNode: *items[i]}
116 | if resources[r].CurId() == it.CurId() {
117 | // don't attempt to add a resource with the same ID
118 | err := rm.Remove(resources[r].CurId())
119 | if err != nil {
120 | return items, err
121 | }
122 | }
123 | }
124 | }
125 |
126 | err = resMap.AppendAll(rm)
127 | if err != nil {
128 | return nil, fmt.Errorf("failed to add generated resource: %w", err)
129 | }
130 | }
131 | return resMap.ToRNodeSlice(), nil
132 | }
133 |
134 | func run(resourceList *framework.ResourceList) error {
135 | var fn helmChartInflatorFunction
136 | err := fn.Config(resourceList.FunctionConfig)
137 | if err != nil {
138 | return fmt.Errorf("failed to configure function: %w", err)
139 | }
140 | resourceList.Items, err = fn.Run(resourceList.Items)
141 | if err != nil {
142 | return fmt.Errorf("failed to run function: %w", err)
143 | }
144 | return nil
145 | }
146 |
147 | func (f *helmChartInflatorFunction) getKind(rn *kyaml.RNode) (string, error) {
148 | meta, err := rn.GetMeta()
149 | if err != nil {
150 | return "", err
151 | }
152 | return meta.Kind, nil
153 | }
154 |
155 | func (f *helmChartInflatorFunction) RenderHelmChartArgs(c []byte) (err error) {
156 | args := &builtins.HelmArgs{}
157 | if err = kyaml.Unmarshal(c, args); err != nil {
158 | return
159 | }
160 | for _, helmChart := range args.HelmCharts {
161 | p := builtins.HelmChartInflationGeneratorPlugin{
162 | HelmGlobals: args.HelmGlobals,
163 | HelmChart: helmChart,
164 | }
165 | if err := p.ValidateArgs(); err != nil {
166 | return err
167 | }
168 | f.plugins = append(f.plugins, p)
169 | }
170 | return nil
171 | }
172 |
173 | func (f *helmChartInflatorFunction) ConfigMapArgs(
174 | bytes []byte) (err error) {
175 | var m map[string]string
176 |
177 | err = kyaml.Unmarshal(bytes, &m)
178 | if err != nil {
179 | return err
180 | }
181 | var p builtins.HelmChartInflationGeneratorPlugin
182 | if val, ok := m["chartHome"]; ok {
183 | p.ChartHome = val
184 | }
185 | if val, ok := m["configHome"]; ok {
186 | p.ConfigHome = val
187 | }
188 | if val, ok := m["name"]; ok {
189 | p.Name = val
190 | }
191 | if val, ok := m["version"]; ok {
192 | p.Version = val
193 | }
194 | if val, ok := m["repo"]; ok {
195 | p.Repo = val
196 | }
197 | if val, ok := m["releaseName"]; ok {
198 | p.ReleaseName = val
199 | }
200 | if val, ok := m["namespace"]; ok {
201 | p.Namespace = val
202 | }
203 | if val, ok := m["includeCRDs"]; ok {
204 | if val == "true" {
205 | p.IncludeCRDs = true
206 | }
207 | }
208 | if val, ok := m["skipTests"]; ok {
209 | if val == "true" {
210 | p.SkipTests = true
211 | }
212 | }
213 | if val, ok := m["valuesFile"]; ok {
214 | p.ValuesFiles = []string{val}
215 | }
216 | if err := p.ValidateArgs(); err != nil {
217 | return err
218 | }
219 | f.plugins = append(f.plugins, p)
220 | return nil
221 | }
222 |
--------------------------------------------------------------------------------
/krm-functions/sig-cli/render-helm-chart/main_test.go:
--------------------------------------------------------------------------------
1 | // Copyright 2022 The Kubernetes Authors.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package main
16 |
17 | import (
18 | "io/ioutil"
19 | "testing"
20 |
21 | "github.com/stretchr/testify/assert"
22 | "sigs.k8s.io/krm-functions-registry/krm-functions/sig-cli/render-helm-chart/third_party/sigs.k8s.io/kustomize/api/builtins"
23 | "sigs.k8s.io/krm-functions-registry/krm-functions/sig-cli/render-helm-chart/third_party/sigs.k8s.io/kustomize/api/types"
24 | "sigs.k8s.io/kustomize/kyaml/yaml"
25 | )
26 |
27 | func TestHelmChartInflatorFunction_Config(t *testing.T) {
28 | tests := map[string]struct {
29 | functionConfig string
30 | expectedErr string
31 | expected []builtins.HelmChartInflationGeneratorPlugin
32 | }{
33 | "invalid function config": {
34 | functionConfig: `invalid`,
35 | expectedErr: "missing Resource metadata",
36 | },
37 | "function config as ConfigMap": {
38 | functionConfig: `
39 | apiVersion: v1
40 | kind: ConfigMap
41 | metadata:
42 | name: myMap
43 | data:
44 | name: minecraft
45 | repo: https://itzg.github.io/minecraft-server-charts
46 | version: 3.1.3
47 | releaseName: test
48 | `,
49 | expected: []builtins.HelmChartInflationGeneratorPlugin{
50 | {
51 | HelmChart: types.HelmChart{
52 | ChartArgs: types.ChartArgs{
53 | Name: "minecraft",
54 | Repo: "https://itzg.github.io/minecraft-server-charts",
55 | Version: "3.1.3",
56 | },
57 | TemplateOptions: types.TemplateOptions{
58 | ReleaseName: "test",
59 | Values: types.Values{
60 | ValuesFiles: []string{"tmp/charts/minecraft/values.yaml"},
61 | ValuesMerge: "override",
62 | },
63 | },
64 | },
65 | },
66 | },
67 | },
68 | "function config as RenderHelmChart": {
69 | functionConfig: `
70 | apiVersion: v1
71 | kind: RenderHelmChart
72 | metadata:
73 | name: myRenderHelmChart
74 | helmCharts:
75 | - chartArgs:
76 | name: minecraft
77 | repo: https://itzg.github.io/minecraft-server-charts
78 | version: 3.1.3
79 | templateOptions:
80 | releaseName: test-1
81 | - chartArgs:
82 | name: minecraft
83 | repo: https://itzg.github.io/minecraft-server-charts
84 | version: 3.1.3
85 | templateOptions:
86 | releaseName: test-2
87 | `,
88 | expected: []builtins.HelmChartInflationGeneratorPlugin{
89 | {
90 | HelmChart: types.HelmChart{
91 | ChartArgs: types.ChartArgs{
92 | Name: "minecraft",
93 | Repo: "https://itzg.github.io/minecraft-server-charts",
94 | Version: "3.1.3",
95 | },
96 | TemplateOptions: types.TemplateOptions{
97 | ReleaseName: "test-1",
98 | Values: types.Values{
99 | ValuesFiles: []string{"tmp/charts/minecraft/values.yaml"},
100 | ValuesMerge: "override",
101 | },
102 | },
103 | },
104 | },
105 | {
106 | HelmChart: types.HelmChart{
107 | ChartArgs: types.ChartArgs{
108 | Name: "minecraft",
109 | Repo: "https://itzg.github.io/minecraft-server-charts",
110 | Version: "3.1.3",
111 | },
112 | TemplateOptions: types.TemplateOptions{
113 | ReleaseName: "test-2",
114 | Values: types.Values{
115 | ValuesFiles: []string{"tmp/charts/minecraft/values.yaml"},
116 | ValuesMerge: "override",
117 | },
118 | },
119 | },
120 | },
121 | },
122 | },
123 | }
124 |
125 | for _, tc := range tests {
126 | var fn helmChartInflatorFunction
127 | node := yaml.MustParse(tc.functionConfig)
128 | err := fn.Config(node)
129 | if tc.expectedErr == "" {
130 | if !assert.NoError(t, err) {
131 | t.FailNow()
132 | }
133 | assert.Equal(t, len(tc.expected), len(fn.plugins))
134 | for i := range tc.expected {
135 | assert.Equal(t, tc.expected[i].HelmChart, fn.plugins[i].HelmChart)
136 | }
137 | } else {
138 | if !assert.Error(t, err) {
139 | t.FailNow()
140 | }
141 | assert.Contains(t, err.Error(), tc.expectedErr)
142 | }
143 | }
144 | }
145 |
146 | func TestHelmChartInflatorFunction_Run(t *testing.T) {
147 | tmpDir, err := ioutil.TempDir("", "")
148 | assert.NoError(t, err)
149 |
150 | tests := map[string]struct {
151 | functionConfig string
152 | expected string
153 | }{
154 | "simple": {
155 | functionConfig: `
156 | apiVersion: v1
157 | kind: RenderHelmChart
158 | metadata:
159 | name: myRenderHelmChart
160 | helmGlobals:
161 | chartHome: ` + tmpDir + `
162 | helmCharts:
163 | - chartArgs:
164 | name: minecraft
165 | repo: https://itzg.github.io/minecraft-server-charts
166 | version: 3.1.3
167 | templateOptions:
168 | releaseName: test-1
169 | - chartArgs:
170 | name: minecraft
171 | repo: https://itzg.github.io/minecraft-server-charts
172 | version: 3.1.3
173 | templateOptions:
174 | releaseName: test-2
175 | `,
176 | expected: `# Source: minecraft/templates/secrets.yaml
177 | apiVersion: v1
178 | kind: Secret
179 | metadata:
180 | name: test-1-minecraft
181 | labels:
182 | app: test-1-minecraft
183 | chart: "minecraft-3.1.3"
184 | release: "test-1"
185 | heritage: "Helm"
186 | type: Opaque
187 | data:
188 | rcon-password: "Q0hBTkdFTUUh"
189 | # Source: minecraft/templates/minecraft-svc.yaml
190 | apiVersion: v1
191 | kind: Service
192 | metadata:
193 | name: test-1-minecraft
194 | labels:
195 | app: test-1-minecraft
196 | chart: "minecraft-3.1.3"
197 | release: "test-1"
198 | heritage: "Helm"
199 | annotations: {}
200 | spec:
201 | type: ClusterIP
202 | ports:
203 | - name: minecraft
204 | port: 25565
205 | targetPort: minecraft
206 | protocol: TCP
207 | selector:
208 | app: test-1-minecraft
209 | # Source: minecraft/templates/secrets.yaml
210 | apiVersion: v1
211 | kind: Secret
212 | metadata:
213 | name: test-2-minecraft
214 | labels:
215 | app: test-2-minecraft
216 | chart: "minecraft-3.1.3"
217 | release: "test-2"
218 | heritage: "Helm"
219 | type: Opaque
220 | data:
221 | rcon-password: "Q0hBTkdFTUUh"
222 | # Source: minecraft/templates/minecraft-svc.yaml
223 | apiVersion: v1
224 | kind: Service
225 | metadata:
226 | name: test-2-minecraft
227 | labels:
228 | app: test-2-minecraft
229 | chart: "minecraft-3.1.3"
230 | release: "test-2"
231 | heritage: "Helm"
232 | annotations: {}
233 | spec:
234 | type: ClusterIP
235 | ports:
236 | - name: minecraft
237 | port: 25565
238 | targetPort: minecraft
239 | protocol: TCP
240 | selector:
241 | app: test-2-minecraft
242 | `,
243 | },
244 | "include CRDs": {
245 | functionConfig: `
246 | apiVersion: v1
247 | kind: RenderHelmChart
248 | metadata:
249 | name: myRenderHelmChart
250 | helmGlobals:
251 | chartHome: ` + tmpDir + `
252 | helmCharts:
253 | - chartArgs:
254 | name: terraform
255 | repo: https://helm.releases.hashicorp.com
256 | version: 1.0.0
257 | templateOptions:
258 | releaseName: terraforming-mars
259 | includeCRDs: true
260 | `,
261 | expected: `kind: CustomResourceDefinition`,
262 | },
263 | }
264 |
265 | for _, tc := range tests {
266 | var fn helmChartInflatorFunction
267 | node := yaml.MustParse(tc.functionConfig)
268 |
269 | err = fn.Config(node)
270 | assert.NoError(t, err)
271 |
272 | items, err := fn.Run(nil)
273 | if !assert.NoError(t, err) {
274 | t.FailNow()
275 | }
276 |
277 | actual := ""
278 | for i := range items {
279 | actual = actual + items[i].MustString()
280 | }
281 | assert.Contains(t, actual, tc.expected)
282 | }
283 | }
284 |
--------------------------------------------------------------------------------
/krm-functions/sig-cli/render-helm-chart/third_party/README.md:
--------------------------------------------------------------------------------
1 | This package is forked from `sigs.k8s.io/kustomize/api/` with version `api/0.8.11`.
--------------------------------------------------------------------------------
/krm-functions/sig-cli/render-helm-chart/third_party/sigs.k8s.io/kustomize/api/builtins/HelmChartInflationGenerator.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021 The Kubernetes Authors.
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | //go:generate HelmChartInflationGeneratorPluginator
5 | package builtins
6 |
7 | import (
8 | "bytes"
9 | "crypto/md5"
10 | "encoding/hex"
11 | "fmt"
12 | "io/ioutil"
13 | "net/http"
14 | "net/url"
15 | "os"
16 | "os/exec"
17 | "path/filepath"
18 | "regexp"
19 | "strings"
20 |
21 | "github.com/imdario/mergo"
22 | "github.com/pkg/errors"
23 | "sigs.k8s.io/krm-functions-registry/krm-functions/sig-cli/render-helm-chart/third_party/sigs.k8s.io/kustomize/api/types"
24 | "sigs.k8s.io/kustomize/api/hasher"
25 | "sigs.k8s.io/kustomize/api/resmap"
26 | "sigs.k8s.io/kustomize/api/resource"
27 | "sigs.k8s.io/yaml"
28 | )
29 |
30 | // Add the given labels to the given field specifications.
31 | type HelmArgs struct {
32 | types.HelmGlobals `json:"helmGlobals,omitempty" yaml:"helmGlobals,omitempty"`
33 | HelmCharts []types.HelmChart `json:"helmCharts,omitempty" yaml:"helmCharts,omitempty"`
34 | }
35 |
36 | type HelmChartInflationGeneratorPlugin struct {
37 | types.HelmGlobals `json:",inline,omitempty" yaml:",inline,omitempty"`
38 | types.HelmChart `json:",inline,omitempty" yaml:",inline,omitempty"`
39 | tmpDir string
40 | }
41 |
42 | const (
43 | valuesMergeOptionMerge = "merge"
44 | valuesMergeOptionOverride = "override"
45 | valuesMergeOptionReplace = "replace"
46 | )
47 |
48 | var legalMergeOptions = []string{
49 | valuesMergeOptionMerge,
50 | valuesMergeOptionOverride,
51 | valuesMergeOptionReplace,
52 | }
53 |
54 | //noinspection GoUnusedGlobalVariable
55 | var KustomizeHelmChartInflationGeneratorPlugin HelmChartInflationGeneratorPlugin
56 |
57 | func (p *HelmChartInflationGeneratorPlugin) establishTmpDir() (err error) {
58 | if p.tmpDir != "" {
59 | // already done.
60 | return nil
61 | }
62 | p.tmpDir, err = ioutil.TempDir("", "kustomize-helm-")
63 | return err
64 | }
65 |
66 | func (p *HelmChartInflationGeneratorPlugin) ValidateArgs() (err error) {
67 | // ChartHome might be written to by the function in a container,
68 | // so it must be under the `/tmp` directory
69 | if p.ChartHome == "" {
70 | p.ChartHome = "tmp/charts"
71 | }
72 |
73 | if len(p.ValuesFiles) == 0 {
74 | p.ValuesFiles = append(p.ValuesFiles, filepath.Join(p.ChartHome, p.Name, "values.yaml"))
75 | }
76 |
77 | if err = p.errIfIllegalValuesMerge(); err != nil {
78 | return err
79 | }
80 |
81 | // ConfigHome is not loaded by the HelmChartInflationGeneratorPlugin, and can be located anywhere.
82 | if p.ConfigHome == "" {
83 | if err = p.establishTmpDir(); err != nil {
84 | return errors.Wrap(
85 | err, "unable to create tmp dir for HELM_CONFIG_HOME")
86 | }
87 | p.ConfigHome = filepath.Join(p.tmpDir, "helm")
88 | }
89 | return nil
90 | }
91 |
92 | func (p *HelmChartInflationGeneratorPlugin) errIfIllegalValuesMerge() error {
93 | if p.ValuesMerge == "" {
94 | // Use the default.
95 | p.ValuesMerge = valuesMergeOptionOverride
96 | return nil
97 | }
98 | for _, opt := range legalMergeOptions {
99 | if p.ValuesMerge == opt {
100 | return nil
101 | }
102 | }
103 | return fmt.Errorf("valuesMerge must be one of %v", legalMergeOptions)
104 | }
105 |
106 | func (p *HelmChartInflationGeneratorPlugin) absChartHome() string {
107 | path, _ := filepath.Abs(p.ChartHome)
108 | return path
109 | }
110 |
111 | func (p *HelmChartInflationGeneratorPlugin) runHelmCommand(
112 | args []string) ([]byte, error) {
113 | stdout := new(bytes.Buffer)
114 | stderr := new(bytes.Buffer)
115 | cmd := exec.Command("helm", args...)
116 | cmd.Stdout = stdout
117 | cmd.Stderr = stderr
118 | env := []string{
119 | fmt.Sprintf("HELM_CONFIG_HOME=%s", p.ConfigHome),
120 | fmt.Sprintf("HELM_CACHE_HOME=%s/.cache", p.ConfigHome),
121 | fmt.Sprintf("HELM_DATA_HOME=%s/.data", p.ConfigHome)}
122 | cmd.Env = append(os.Environ(), env...)
123 | err := cmd.Run()
124 | if err != nil {
125 | helm := "helm"
126 | err = errors.Wrap(
127 | fmt.Errorf(
128 | "unable to run: '%s %s' with env=%s (is '%s' installed?)",
129 | helm, strings.Join(args, " "), env, helm),
130 | stderr.String(),
131 | )
132 | }
133 | return stdout.Bytes(), err
134 | }
135 |
136 | // createNewMergedValuesFiles replaces/merges original values file with ValuesInline.
137 | func (p *HelmChartInflationGeneratorPlugin) createNewMergedValuesFiles(path string) (
138 | string, error) {
139 | pValues, err := ioutil.ReadFile(path)
140 | if err != nil {
141 | if u, urlErr := url.Parse(path); urlErr == nil {
142 | if u.Scheme == "http" || u.Scheme == "https" {
143 | resp, err := http.Get(path)
144 | if err != nil {
145 | return "", err
146 | }
147 | defer resp.Body.Close()
148 | pValues, err = ioutil.ReadAll(resp.Body)
149 | if err != nil {
150 | return "", err
151 | }
152 | } else { // url scheme is not http or https
153 | return "", fmt.Errorf("unsupported URL scheme: %s", path)
154 | }
155 | } else { // invalid path and invalid URL
156 | return "", fmt.Errorf(
157 | "could not read provided values file %q: when reading as file path, received error %v; when reading as URL, received error %v",
158 | path, err, urlErr)
159 | }
160 | } else {
161 | // we want to pass in the absolute path into writeValuesBytes
162 | path, err = filepath.Abs(path)
163 | if err != nil {
164 | return "", err
165 | }
166 | }
167 | if p.ValuesMerge == valuesMergeOptionMerge ||
168 | p.ValuesMerge == valuesMergeOptionOverride {
169 | if err = p.replaceValuesInline(pValues); err != nil {
170 | return "", err
171 | }
172 | }
173 | var b []byte
174 | b, err = yaml.Marshal(p.ValuesInline)
175 | if err != nil {
176 | return "", err
177 | }
178 | return p.writeValuesBytes(b, path)
179 | }
180 |
181 | func (p *HelmChartInflationGeneratorPlugin) replaceValuesInline(pValues []byte) error {
182 | var err error
183 | chValues := make(map[string]interface{})
184 | if err = yaml.Unmarshal(pValues, &chValues); err != nil {
185 | return err
186 | }
187 | switch p.ValuesMerge {
188 | case valuesMergeOptionOverride:
189 | err = mergo.Merge(
190 | &chValues, p.ValuesInline, mergo.WithOverride)
191 | case valuesMergeOptionMerge:
192 | err = mergo.Merge(&chValues, p.ValuesInline)
193 | }
194 | p.ValuesInline = chValues
195 | return err
196 | }
197 |
198 | // Write a absolute path file in the tmp file system.
199 | func (p *HelmChartInflationGeneratorPlugin) writeValuesBytes(
200 | b []byte, path string) (string, error) {
201 | if err := p.establishTmpDir(); err != nil {
202 | return "", fmt.Errorf("cannot create tmp dir to write helm values")
203 | }
204 | // use a hash of the provided path to generate a unique, valid filename
205 | hash := md5.Sum([]byte(path))
206 | newPath := filepath.Join(p.tmpDir, p.Name+"-kustomize-values-"+hex.EncodeToString(hash[:])+".yaml")
207 | return newPath, ioutil.WriteFile(newPath, b, 0644)
208 | }
209 |
210 | func (p *HelmChartInflationGeneratorPlugin) cleanup() {
211 | if p.tmpDir != "" {
212 | os.RemoveAll(p.tmpDir)
213 | }
214 | }
215 |
216 | func (p *HelmChartInflationGeneratorPlugin) Generate() (rm resmap.ResMap, err error) {
217 | defer p.cleanup()
218 | if err = p.checkHelmVersion(); err != nil {
219 | return nil, err
220 | }
221 | if _, exists := p.chartExistsLocally(); !exists {
222 | if _, err := p.runHelmCommand(p.pullCommand()); err != nil {
223 | return nil, err
224 | }
225 | }
226 | var valuesFiles []string
227 | for _, valuesFile := range p.ValuesFiles {
228 | file, err := p.createNewMergedValuesFiles(valuesFile)
229 | if err != nil {
230 | return nil, err
231 | }
232 | valuesFiles = append(valuesFiles, file)
233 | }
234 | p.ValuesFiles = valuesFiles
235 |
236 | var stdout []byte
237 | stdout, err = p.runHelmCommand(p.templateCommand())
238 | if err != nil {
239 | return nil, err
240 | }
241 |
242 | factory := NewResMapFactory()
243 | rm, err = factory.NewResMapFromBytes(stdout)
244 | if err == nil {
245 | return rm, nil
246 | }
247 | // try to remove the contents before first "---" because
248 | // helm may produce messages to stdout before it
249 | stdoutStr := string(stdout)
250 | if idx := strings.Index(stdoutStr, "---"); idx != -1 {
251 | return factory.NewResMapFromBytes([]byte(stdoutStr[idx:]))
252 | }
253 | return nil, err
254 | }
255 |
256 | func (p *HelmChartInflationGeneratorPlugin) templateCommand() []string {
257 | args := []string{"template"}
258 | if p.ReleaseName != "" {
259 | args = append(args, p.ReleaseName)
260 | }
261 | if p.Namespace != "" {
262 | args = append(args, "--namespace", p.Namespace)
263 | }
264 | if p.NameTemplate != "" {
265 | args = append(args, "--name-template", p.NameTemplate)
266 | }
267 | if p.Name != "" {
268 | args = append(args, filepath.Join(p.absChartHome(), p.Name))
269 | }
270 | for _, valuesFile := range p.ValuesFiles {
271 | args = append(args, "-f", valuesFile)
272 | }
273 | for _, apiVer := range p.ApiVersions {
274 | args = append(args, "--api-versions", apiVer)
275 | }
276 | if p.ReleaseName == "" {
277 | // AFAICT, this doesn't work as intended due to a bug in helm.
278 | // See https://github.com/helm/helm/issues/6019
279 | // I've tried placing the flag before and after the name argument.
280 | args = append(args, "--generate-name")
281 | }
282 | if p.Description != "" {
283 | args = append(args, "--description", p.Description)
284 | }
285 | if p.IncludeCRDs {
286 | args = append(args, "--include-crds")
287 | }
288 | if p.SkipTests {
289 | args = append(args, "--skip-tests")
290 | }
291 | return args
292 | }
293 |
294 | func (p *HelmChartInflationGeneratorPlugin) pullCommand() []string {
295 | args := []string{
296 | "pull",
297 | "--untar",
298 | "--untardir", p.absChartHome()}
299 | if p.Repo != "" {
300 | args = append(args, "--repo", p.Repo)
301 | }
302 | if p.Name != "" {
303 | args = append(args, p.Name)
304 | }
305 | if p.Version != "" {
306 | args = append(args, "--version", p.Version)
307 | }
308 | return args
309 | }
310 |
311 | // chartExistsLocally will return true if the chart does exist in
312 | // local chart home.
313 | func (p *HelmChartInflationGeneratorPlugin) chartExistsLocally() (string, bool) {
314 | path := filepath.Join(p.absChartHome(), p.Name)
315 | s, err := os.Stat(path)
316 | if err != nil {
317 | return path, false
318 | }
319 | return path, s.IsDir()
320 | }
321 |
322 | // checkHelmVersion will return an error if the helm version is not V3
323 | func (p *HelmChartInflationGeneratorPlugin) checkHelmVersion() error {
324 | stdout, err := p.runHelmCommand([]string{"version", "-c", "--short"})
325 | if err != nil {
326 | return err
327 | }
328 | r, err := regexp.Compile(`v?\d+(\.\d+)+`)
329 | if err != nil {
330 | return err
331 | }
332 | v := r.FindString(string(stdout))
333 | if v == "" {
334 | return fmt.Errorf("cannot find version string in %s", string(stdout))
335 | }
336 | if v[0] == 'v' {
337 | v = v[1:]
338 | }
339 | majorVersion := strings.Split(v, ".")[0]
340 | if majorVersion != "3" {
341 | return fmt.Errorf("this HelmChartInflationGeneratorPlugin requires helm V3 but got v%s", v)
342 | }
343 | return nil
344 | }
345 |
346 | func NewResMapFactory() *resmap.Factory {
347 | resourceFactory := resource.NewFactory(&hasher.Hasher{})
348 | resourceFactory.IncludeLocalConfigs = true
349 | return resmap.NewFactory(resourceFactory)
350 | }
351 |
--------------------------------------------------------------------------------
/krm-functions/sig-cli/render-helm-chart/third_party/sigs.k8s.io/kustomize/api/types/helmchartargs.go:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The Kubernetes Authors.
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | package types
5 |
6 | type HelmGlobals struct {
7 | // ChartHome is a file path to a directory containing a subdirectory for
8 | // each chart to be included in the output. The default value of this field
9 | // is "tmp/charts".
10 | // At runtime, the function will look for the chart under {ChartHome}. If it
11 | // is there, the function will use it as found. If it is not there, the
12 | // function will attempt to pull it and put it in {ChartHome}.
13 | // When run as a container function, local directories must be mounted into
14 | // the container in order for the function to use them.
15 | // If the function needs to pull the helm chart while running in a container,
16 | // ChartHome MUST start with "tmp/".
17 | ChartHome string `json:"chartHome,omitempty" yaml:"chartHome,omitempty"`
18 |
19 | // ConfigHome defines a value that the function should pass to helm via
20 | // the HELM_CONFIG_HOME environment variable. The function doesn't attempt
21 | // to read or write this directory.
22 | // If omitted, {tmpDir}/helm is used, where {tmpDir} is some temporary
23 | // directory created by the function for the benefit of helm.
24 | // Likewise, the function sets
25 | // HELM_CACHE_HOME={ConfigHome}/.cache
26 | // HELM_DATA_HOME={ConfigHome}/.data
27 | // for the helm subprocess.
28 | ConfigHome string `json:"configHome,omitempty" yaml:"configHome,omitempty"`
29 | }
30 |
31 | type HelmChart struct {
32 | // ChartArgs encapsulates information about the chart being inflated, including
33 | // the chart's name, version, and repo.
34 | ChartArgs `json:"chartArgs,omitempty" yaml:"chartArgs,omitempty"`
35 |
36 | // TemplateOptions are fields that become flags to `helm template` when
37 | // the helm chart is being rendered.
38 | TemplateOptions `json:"templateOptions,omitempty" yaml:"templateOptions,omitempty"`
39 | }
40 |
41 | type ChartArgs struct {
42 | // Name is the name of the chart, e.g. 'minecraft'.
43 | Name string `json:"name,omitempty" yaml:"name,omitempty"`
44 |
45 | // Version is the version of the chart, e.g. '3.1.3'
46 | Version string `json:"version,omitempty" yaml:"version,omitempty"`
47 |
48 | // Repo is a URL locating the chart on the internet.
49 | // This is the argument to helm's `--repo` flag, e.g.
50 | // `https://itzg.github.io/minecraft-server-charts`.
51 | Repo string `json:"repo,omitempty" yaml:"repo,omitempty"`
52 | }
53 |
54 | type TemplateOptions struct {
55 | // ApiVersions is the kubernetes apiversions used for Capabilities.APIVersions
56 | ApiVersions []string `json:"apiVerions,omitempty" yaml:"apiVersions,omitempty"`
57 |
58 | // ReleaseName replaces RELEASE-NAME in chart template output,
59 | // making a particular inflation of a chart unique with respect to
60 | // other inflations of the same chart in a cluster. It's the first
61 | // argument to the helm `install` and `template` commands, i.e.
62 | // helm install {RELEASE-NAME} {chartName}
63 | // helm template {RELEASE-NAME} {chartName}
64 | // If omitted, the flag --generate-name is passed to 'helm template'.
65 | ReleaseName string `json:"releaseName,omitempty" yaml:"releaseName,omitempty"`
66 |
67 | // Namespace set the target namespace for a release. It is .Release.Namespace
68 | // in the helm template
69 | Namespace string `json:"namespace,omitempty" yaml:"namespace,omitempty"`
70 |
71 | // Description is a custom description to add when rendering the helm chart.
72 | Description string `json:"description,omitempty" yaml:"description,omitempty"`
73 |
74 | // NameTemplate is for specifying the name template used to name the release.
75 | NameTemplate string `json:"nameTemplate,omitempty" yaml:"nameTemplate,omitempty"`
76 |
77 | // IncludeCRDs specifies if Helm should also generate CustomResourceDefinitions.
78 | // Defaults to false.
79 | IncludeCRDs bool `json:"includeCRDs,omitempty" yaml:"includeCRDs,omitempty"`
80 |
81 | // SkipTests skips tests from templated output.
82 | SkipTests bool `json:"skipTests,omitempty" yaml:"skipTests,omitempty"`
83 |
84 | // Values are values that are specified inline or in a yaml file to use.
85 | Values `json:"values,omitempty" yaml:"values,omitempty"`
86 | }
87 |
88 | type Values struct {
89 | // ValuesFiles is a list of local file paths to values files to use instead of
90 | // the default values that accompanied the chart.
91 | // The default values are in '{ChartHome}/{Name}/values.yaml'.
92 | ValuesFiles []string `json:"valuesFiles,omitempty" yaml:"valuesFiles,omitempty"`
93 |
94 | // ValuesInline holds value mappings specified directly,
95 | // rather than in a separate file.
96 | ValuesInline map[string]interface{} `json:"valuesInline,omitempty" yaml:"valuesInline,omitempty"`
97 |
98 | // ValuesMerge specifies how to treat ValuesInline with respect to Values.
99 | // Legal values: 'merge', 'override', 'replace'.
100 | // Defaults to 'override'.
101 | ValuesMerge string `json:"valuesMerge,omitempty" yaml:"valuesMerge,omitempty"`
102 | }
103 |
--------------------------------------------------------------------------------
/publishers/README.md:
--------------------------------------------------------------------------------
1 | # Publishers
2 |
3 | This directory is the home for all published KRM functions metadata. Each publisher should create their own
4 | subdirectory containing:
5 |
6 | - An OWNERS file containing a list of owners of the publisher
7 | - A README.md file with a description of who the publisher is
8 | - A `functions` directory, containing a file for each published KRM function. The KRM function metadata file should be named after the function,
9 | `{FUNCTION-NAME}.yaml`. This file should be a kubernetes object of type KRMFunctionDefinition,
10 | which is defined in the [Catalog KEP].
11 | - A `catalogs` directory, containing a file for each published functions Catalog. Each catalog file should be named with the date it was
12 | published, in the form `v{YYYY}{MM}{DD}.yaml`, e.g. `v20220225.yaml`.
13 |
14 | See [SIG-CLI functions] as an example.
15 |
16 | [SIG-CLI functions]: (https://github.com/kubernetes-sigs/krm-functions-registry/tree/main/publishers/sig-cli)
17 |
18 | [Catalog KEP]: https://github.com/kubernetes/enhancements/tree/master/keps/sig-cli/2906-kustomize-function-catalog#function-metadata-schema
--------------------------------------------------------------------------------
/publishers/sig-cli/OWNERS:
--------------------------------------------------------------------------------
1 | # See the OWNERS docs at https://go.k8s.io/owners
2 |
3 | approvers:
4 | - sig-cli-functions-approvers
5 |
--------------------------------------------------------------------------------
/publishers/sig-cli/README.md:
--------------------------------------------------------------------------------
1 | This directory contains published KRM function metadata and catalogs for
2 | [SIG-CLI](https://github.com/kubernetes/community/tree/master/sig-cli).
--------------------------------------------------------------------------------
/publishers/sig-cli/catalogs/v20220225.yaml:
--------------------------------------------------------------------------------
1 | # Copyright 2022 The Kubernetes Authors.
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | # This file is just a placeholder until we have a published catalog.
--------------------------------------------------------------------------------
/publishers/sig-cli/functions/render-helm-chart.yaml:
--------------------------------------------------------------------------------
1 | # Copyright 2022 The Kubernetes Authors.
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | # TODO: Add CI to validate the metadata here.
16 |
17 | apiVersion: config.kubernetes.io/v1alpha1
18 | kind: KRMFunctionDefinition
19 | spec:
20 | group: config.kubernetes.io
21 | description: "The `render-helm-chart` function renders a local or remote Helm chart."
22 | publisher: https://github.com/kubernetes/community/tree/master/sig-cli
23 | names:
24 | kind: RenderHelmChart
25 | versions:
26 | - name: v1
27 | idempotent: true
28 | license: Apache 2.0
29 | maintainers:
30 | - natashasarkar@google.com
31 | - mengqiy@google.com
32 | - katrina.verey@shopify.com
33 | usage: https://github.com/kubernetes-sigs/krm-functions-registry/blob/main/krm-functions/sig-cli/render-helm-chart/README.md
34 | examples:
35 | - https://github.com/kubernetes-sigs/krm-functions-registry/blob/main/krm-functions/sig-cli/render-helm-chart/examples/render-helm-chart-kustomize-inline-values/README.md
36 | - https://github.com/kubernetes-sigs/krm-functions-registry/blob/main/krm-functions/sig-cli/render-helm-chart/examples/render-helm-chart-kustomize-values-files/README.md
37 | runtime:
38 | container:
39 | image: us.gcr.io/k8s-artifacts-prod/krm-functions/render-helm-chart:unstable
40 | requireNetwork: true
41 | requireStorageMount: true
42 | schema:
43 | openAPIV3Schema:
44 | properties:
45 | apiVersion:
46 | type: string
47 | kind:
48 | type: string
49 | metadata:
50 | type: object
51 | properties:
52 | name:
53 | type: string
54 | minLength: 1
55 | required:
56 | - name
57 | helmGlobals:
58 | description: parameters applied to all helm charts.
59 | type: object
60 | properties:
61 | chartHome:
62 | description:
63 | type: string
64 | configHome:
65 | description:
66 | type: string
67 | helmCharts:
68 | description: an array of helm chart parameters.
69 | type: array
70 | items:
71 | type: object
72 | description: parameters to configure the helm chart rendering.
73 | properties:
74 | chartArgs:
75 | description: arguments that describe the chart being rendered.
76 | type: object
77 | properties:
78 | name:
79 | description: the name of the chart.
80 | type: string
81 | version:
82 | description: the version of the chart.
83 | type: string
84 | repo:
85 | description: URL locating the chart on the internet
86 | type: string
87 | templateOptions:
88 | description: a collection of fields that map to flag options of `helm template`.
89 | type: object
90 | properties:
91 | apiVersions:
92 | description: kubernetes api versions used for Capabilities.APIVersions
93 | type: array
94 | items:
95 | type: string
96 | releaseName:
97 | description: replaces RELEASE_NAME in the chart template output
98 | type: string
99 | namespace:
100 | description: sets the target namespace for a release (`.Release.Namespace` in the template)
101 | type: string
102 | nameTemplate:
103 | description: specifies the template used to name the release
104 | type: string
105 | includeCRDs:
106 | description: specifies if Helm should also generate CustomResourceDefinitions. Legal values are "true", "false" (default).
107 | type: bool
108 | skipTests:
109 | description: if set, skip tests from templated output. Legal values are "true", "false" (default).
110 | type: bool
111 | values:
112 | description: values to use instead of the default values that accompany the chart.
113 | type: object
114 | properties:
115 | valuesFiles:
116 | description: remote or local filepaths to use instead of the default values that accompanied the chart. The default values are in '{chartHome}/{name}/values.yaml', where `chartHome` and `name` are the parameters defined above.
117 | type: array
118 | items:
119 | type: string
120 | valuesInline:
121 | description: values defined inline to use instead of default values that accompany the chart.
122 | type: object
123 | additionalProperties:
124 | type: string
125 | valuesMerge:
126 | description: valuesMerge specifies how to treat ValuesInline with respect to ValuesFiles. Legal values are 'merge', 'override' (default), 'replace'.
127 | type: string
128 |
--------------------------------------------------------------------------------
/site/README.md:
--------------------------------------------------------------------------------
1 | # Site \[TODO\]
2 |
3 | This directory will contain the source code for the site contents that will be used to display
4 | the published functions metadata.
--------------------------------------------------------------------------------
/test.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # Copyright 2022 The Kubernetes Authors.
4 | #
5 | # Licensed under the Apache License, Version 2.0 (the "License");
6 | # you may not use this file except in compliance with the License.
7 | # You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing, software
12 | # distributed under the License is distributed on an "AS IS" BASIS,
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | # See the License for the specific language governing permissions and
15 | # limitations under the License.
16 |
17 | make all
18 |
--------------------------------------------------------------------------------
/tests/e2e_test.go:
--------------------------------------------------------------------------------
1 | // Copyright 2021 The Kubernetes Authors
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package tests
16 |
17 | import (
18 | "testing"
19 |
20 | "github.com/GoogleContainerTools/kpt/pkg/test/runner"
21 | )
22 |
23 | // TestExamples runs all in-tree examples in the ../krm-functions/sig-cli directory as tests.
24 | //
25 | // It expects each subdirectory to have a '.expected' folder with the following files:
26 | // - 'config.yaml' has the configuration, containing the following fields:
27 | // - 'exitCode': The expected exit code (default 0)
28 | // - 'skip': If set to true, this test will be skipped (default false)
29 | // - 'exec.sh' is a script to run in the current directory. For example, to test a kustomization
30 | // file output, this can be something like `kustomize build` > resources.yaml.
31 | // - 'diff.patch' is the expected diff output between original directory files and
32 | // files after exec script running.
33 | //
34 | func TestExamples(t *testing.T) {
35 | cases, err := runner.ScanTestCases("../krm-functions")
36 | if err != nil {
37 | t.Fatalf(err.Error())
38 | }
39 | for _, c := range *cases {
40 | c := c
41 | c.Config.ImagePullPolicy = "never"
42 | t.Run(c.Path, func(t *testing.T) {
43 | r, err := runner.NewRunner(t, c, c.Config.TestType)
44 | if err != nil {
45 | t.Fatalf("error creating test runner: %s", err)
46 | }
47 | if r.Skip() {
48 | t.Skip()
49 | }
50 | err = r.Run()
51 | if err != nil {
52 | t.Fatalf("error running test: %s", err)
53 | }
54 | })
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/tests/go.mod:
--------------------------------------------------------------------------------
1 | module sigs.k8s.io/krm-functions-registry/tests
2 |
3 | go 1.17
4 |
5 | require (
6 | github.com/GoogleContainerTools/kpt v1.0.0-beta.13.0.20220208222711-5169954be82f
7 | github.com/stretchr/testify v1.7.0
8 | k8s.io/kube-openapi v0.0.0-20211109043139-026bd182f079
9 | sigs.k8s.io/kustomize/kyaml v0.13.3
10 | sigs.k8s.io/yaml v1.2.0
11 | )
12 |
13 | require (
14 | github.com/PuerkitoBio/purell v1.1.1 // indirect
15 | github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
16 | github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a // indirect
17 | github.com/davecgh/go-spew v1.1.1 // indirect
18 | github.com/go-errors/errors v1.4.0 // indirect
19 | github.com/go-openapi/jsonpointer v0.19.5 // indirect
20 | github.com/go-openapi/jsonreference v0.19.5 // indirect
21 | github.com/go-openapi/swag v0.19.14 // indirect
22 | github.com/google/go-cmp v0.5.6 // indirect
23 | github.com/josharian/intern v1.0.0 // indirect
24 | github.com/mailru/easyjson v0.7.6 // indirect
25 | github.com/mitchellh/mapstructure v1.4.1 // indirect
26 | github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect
27 | github.com/pkg/errors v0.9.1 // indirect
28 | github.com/pmezard/go-difflib v1.0.0 // indirect
29 | github.com/xlab/treeprint v0.0.0-20181112141820-a009c3971eca // indirect
30 | golang.org/x/net v0.0.0-20210520170846-37e1c6afe023 // indirect
31 | golang.org/x/text v0.3.6 // indirect
32 | gopkg.in/yaml.v2 v2.4.0 // indirect
33 | gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
34 | k8s.io/utils v0.0.0-20210820185131-d34e5cb4466e // indirect
35 | )
36 |
37 | replace sigs.k8s.io/kustomize/kyaml => sigs.k8s.io/kustomize/kyaml v0.13.4-0.20220224183231-6950a0d24640
38 |
--------------------------------------------------------------------------------
/tests/testutils.go:
--------------------------------------------------------------------------------
1 | // Copyright 2022 The Kubernetes Authors.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package tests
16 |
17 | const KrmFunctionSchema = `swagger: "2.0"
18 | info:
19 | title: KRM Function Metadata
20 | version: v1alpha1
21 | definitions:
22 | KRMFunctionDefinition:
23 | type: object
24 | description: |
25 | KRMFunctionDefinition is metadata that defines a KRM function
26 | the same way a CustomResourceDefinition defines a custom resource.
27 | x-kubernetes-group-version-kind:
28 | - group: config.kubernetes.io
29 | kind: KRMFunctionDefinition
30 | version: v1alpha1
31 | required:
32 | - apiVersion
33 | - kind
34 | - spec
35 | properties:
36 | apiVersion:
37 | description: apiVersion of KRMFunctionDefinition. i.e. config.kubernetes.io/v1alpha1
38 | type: string
39 | enum:
40 | - config.kubernetes.io/v1alpha1
41 | kind:
42 | description: kind of the KRMFunctionDefinition. It must be KRMFunctionDefinition.
43 | type: string
44 | enum:
45 | - KRMFunctionDefinition
46 | spec:
47 | type: object
48 | description: spec contains the metadata for a KRM function.
49 | required:
50 | - group
51 | - names
52 | - description
53 | - publisher
54 | - versions
55 | properties:
56 | group:
57 | description: group of the functionConfig
58 | type: string
59 | description:
60 | description: brief description of the KRM function.
61 | type: string
62 | publisher:
63 | description: the entity (e.g. organization) that produced and owns this KRM function.
64 | type: string
65 | names:
66 | description: the resource and kind names for the KRM function
67 | type: object
68 | required:
69 | - kind
70 | properties:
71 | kind:
72 | description: the Kind of the functionConfig
73 | type: string
74 | versions:
75 | description: the versions of the functionConfig
76 | type: array
77 | items:
78 | type: object
79 | required:
80 | - name
81 | - schema
82 | - idempotent
83 | - runtime
84 | - usage
85 | - examples
86 | - license
87 | properties:
88 | name:
89 | description: Version of the functionConfig
90 | type: string
91 | schema:
92 | description: a URI pointing to the schema of the functionConfig
93 | type: object
94 | required:
95 | - openAPIV3Schema
96 | properties:
97 | openAPIV3Schema:
98 | description: openAPIV3Schema is the OpenAPI v3 schema to use for validation
99 | # kube-openapi validation doesn't support references, and inlining this ref is extremely tedious
100 | # $ref: "#/definitions/io.k8s.apiextensions-apiserver.pkg.apis.apiextensions.v1.JSONSchemaProps"
101 | idempotent:
102 | description: If the function is idempotent.
103 | type: boolean
104 | usage:
105 | description: |
106 | A URI pointing to a README.md that describe the details of how to
107 | use the KRM function. It should at least cover what the function
108 | does and what functionConfig does it support and it should give
109 | detailed explanation about each field in the functionConfig.
110 | type: string
111 | examples:
112 | description: |
113 | A list of URIs that point to README.md files. At least one example
114 | must be provided. Each README.md should cover an example. It
115 | should at least cover how to get input resources, how to run it
116 | and what is the expected output.
117 | type: array
118 | items:
119 | type: string
120 | license:
121 | description: The license of the KRM function.
122 | type: string
123 | enum:
124 | - Apache 2.0
125 | maintainers:
126 | description: |
127 | The maintainers for the function. It should only be used
128 | when the maintainers are different from the ones in
129 | spec.maintainers. When this field is specified, it
130 | override spec.maintainers.
131 | type: array
132 | items:
133 | type: string
134 | runtime:
135 | description: |
136 | The runtime information about the KRM function. At least one of
137 | container and exec must be set.
138 | type: object
139 | properties:
140 | container:
141 | description: The runtime information for container-based KRM function.
142 | type: object
143 | required:
144 | - image
145 | properties:
146 | image:
147 | description: The image name of the KRM function.
148 | type: string
149 | sha256:
150 | description: |
151 | The digest of the image that can be verified against. It
152 | is required only when the image is using semver.
153 | type: string
154 | requireNetwork:
155 | description: If network is required to run this function.
156 | type: boolean
157 | requireStorageMount:
158 | description: If storage mount is required to run this function.
159 | type: boolean
160 | exec:
161 | description: The runtime information for exec-based KRM function.
162 | type: object
163 | required:
164 | - platform
165 | properties:
166 | platforms:
167 | description: Per platform runtime information.
168 | type: array
169 | items:
170 | type: object
171 | required:
172 | - bin
173 | - os
174 | - arch
175 | - uri
176 | - sha256
177 | properties:
178 | bin:
179 | description: The binary name.
180 | type: string
181 | os:
182 | description: The target operating system to run the KRM function.
183 | type: string
184 | enum:
185 | - linux
186 | - darwin
187 | - windows
188 | arch:
189 | description: The target architecture to run the KRM function.
190 | type: string
191 | enum:
192 | - amd64
193 | - arm64
194 | uri:
195 | description: The location to download the binary.
196 | type: string
197 | sha256:
198 | description: The degist of the binary that can be used to verify the binary.
199 | type: string
200 | home:
201 | description: A URI pointing the home page of the KRM function.
202 | type: string
203 | maintainers:
204 | description: The maintainers for the function.
205 | type: array
206 | items:
207 | type: string
208 | tags:
209 | description: |
210 | The tags (or keywords) of the function. e.g. mutator, validator,
211 | generator, prefix, GCP.
212 | type: array
213 | items:
214 | type: string
215 | paths: {}
216 | `
217 |
--------------------------------------------------------------------------------
/tests/validate-metadata_test.go:
--------------------------------------------------------------------------------
1 | // Copyright 2022 The Kubernetes Authors.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package tests
16 |
17 | import (
18 | "encoding/json"
19 | "os"
20 | "path/filepath"
21 | "testing"
22 |
23 | "github.com/stretchr/testify/assert"
24 | "github.com/stretchr/testify/require"
25 | "k8s.io/kube-openapi/pkg/validation/spec"
26 | "k8s.io/kube-openapi/pkg/validation/strfmt"
27 | "k8s.io/kube-openapi/pkg/validation/validate"
28 | "sigs.k8s.io/kustomize/kyaml/fn/framework"
29 | k8syaml "sigs.k8s.io/yaml"
30 | )
31 |
32 | // TestValidateMetadata validates that the function metadata in each function metadata
33 | // file of the publishers directory is a valid KRMFunctionDefinition.
34 | func TestValidateMetadata(t *testing.T) {
35 | assert.NoError(t, os.Chdir("../publishers"))
36 | publishers, err := os.ReadDir(".")
37 | assert.NoError(t, err)
38 |
39 | for _, publisher := range publishers {
40 | if publisher.IsDir() {
41 | functionDir := filepath.Join(publisher.Name(), "functions")
42 | functions, err := os.ReadDir(functionDir)
43 | assert.NoError(t, err)
44 |
45 | for _, function := range functions {
46 | validateFunctionMetadata(t, filepath.Join(functionDir, function.Name()))
47 | }
48 | }
49 | }
50 | }
51 |
52 | func validateFunctionMetadata(t *testing.T, path string) {
53 | functionMetadata, err := os.ReadFile(path)
54 | require.NoError(t, err)
55 |
56 | schemaJSON, err := k8syaml.YAMLToJSON([]byte(KrmFunctionSchema))
57 | require.NoError(t, err)
58 |
59 | swagger := &spec.Swagger{}
60 | require.NoError(t, swagger.UnmarshalJSON(schemaJSON))
61 |
62 | var input map[string]interface{}
63 | inputJSON, err := k8syaml.YAMLToJSON(functionMetadata)
64 | require.NoError(t, err)
65 | require.NoError(t, json.Unmarshal(inputJSON, &input))
66 |
67 | schema := swagger.Definitions["KRMFunctionDefinition"]
68 | schemaValidationError := validate.AgainstSchema(&schema,
69 | input, strfmt.Default)
70 |
71 | require.NoError(t, schemaValidationError)
72 |
73 | var def framework.KRMFunctionDefinition
74 | err = k8syaml.Unmarshal(functionMetadata, &def)
75 | require.NoError(t, err)
76 | }
77 |
--------------------------------------------------------------------------------