Skip to content

Commit e311d0a

Browse files
add helm plugin to distribute the projects
1 parent eae8b21 commit e311d0a

File tree

106 files changed

+5049
-23
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

106 files changed

+5049
-23
lines changed
+110
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
name: Helm Testdata Sample
2+
3+
on:
4+
push:
5+
paths:
6+
- 'testdata/project-v4-with-plugins/**'
7+
- 'testdata/project-v4-multigroup/**'
8+
- '.github/workflows/test-helm-samples.yml'
9+
pull_request:
10+
paths:
11+
- 'testdata/project-v4-with-plugins/**'
12+
- 'testdata/project-v4-multigroup/**'
13+
- '.github/workflows/test-helm-samples.yml'
14+
15+
jobs:
16+
helm-test-project-v4-with-plugins:
17+
runs-on: ubuntu-latest
18+
strategy:
19+
fail-fast: true
20+
if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository
21+
steps:
22+
- name: Checkout repository
23+
uses: actions/checkout@v4
24+
25+
- name: Setup Go
26+
uses: actions/setup-go@v5
27+
with:
28+
go-version: '~1.22'
29+
30+
- name: Install the latest version of kind
31+
run: |
32+
curl -Lo ./kind https://kind.sigs.k8s.io/dl/latest/kind-linux-amd64
33+
chmod +x ./kind
34+
sudo mv ./kind /usr/local/bin/kind
35+
36+
- name: Verify kind installation
37+
run: kind version
38+
39+
- name: Create kind cluster
40+
run: kind create cluster
41+
42+
- name: Prepare project-v4-with-plugins
43+
run: |
44+
cd testdata/project-v4-with-plugins/
45+
go mod tidy
46+
make docker-build IMG=project-v4-with-plugins:v0.1.0
47+
kind load docker-image project-v4-with-plugins:v0.1.0
48+
49+
- name: Install Helm
50+
run: |
51+
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
52+
53+
- name: Verify Helm installation
54+
run: helm version
55+
56+
- name: Lint Helm chart for project-v4-with-plugins
57+
run: |
58+
helm lint testdata/project-v4-with-plugins/dist/chart
59+
60+
- name: Install Helm chart for project-v4-with-plugins
61+
run: |
62+
helm install my-release testdata/project-v4-with-plugins/dist/chart --create-namespace --namespace project-v4-with-plugins-system
63+
64+
helm-test-project-v4-multigroup:
65+
runs-on: ubuntu-latest
66+
strategy:
67+
fail-fast: true
68+
if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository
69+
steps:
70+
- name: Checkout repository
71+
uses: actions/checkout@v4
72+
73+
- name: Setup Go
74+
uses: actions/setup-go@v5
75+
with:
76+
go-version: '~1.22'
77+
78+
- name: Install the latest version of kind
79+
run: |
80+
curl -Lo ./kind https://kind.sigs.k8s.io/dl/latest/kind-linux-amd64
81+
chmod +x ./kind
82+
sudo mv ./kind /usr/local/bin/kind
83+
84+
- name: Verify kind installation
85+
run: kind version
86+
87+
- name: Create kind cluster
88+
run: kind create cluster
89+
90+
- name: Prepare project-v4-multigroup
91+
run: |
92+
cd testdata/project-v4-multigroup/
93+
go mod tidy
94+
make docker-build IMG=project-v4-multigroup:v0.1.0
95+
kind load docker-image project-v4-multigroup:v0.1.0
96+
97+
- name: Install Helm
98+
run: |
99+
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
100+
101+
- name: Verify Helm installation
102+
run: helm version
103+
104+
- name: Lint Helm chart for project-v4-multigroup
105+
run: |
106+
helm lint testdata/project-v4-multigroup/dist/chart
107+
108+
- name: Install Helm chart for project-v4-multigroup
109+
run: |
110+
helm install my-release-multigroup testdata/project-v4-multigroup/dist/chart --create-namespace --namespace project-v4-multigroup-system

Makefile

+10-1
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ lint-fix: golangci-lint ## Run golangci-lint linter and perform fixes
9797

9898
.PHONY: yamllint
9999
yamllint:
100-
@files=$$(find testdata -name '*.yaml' ! -path 'testdata/*/dist/install.yaml'); \
100+
@files=$$(find testdata -name '*.yaml' ! -path 'testdata/*/dist/*'); \
101101
docker run --rm $$(tty -s && echo "-it" || echo) -v $(PWD):/data cytopia/yamllint:latest $$files -d "{extends: relaxed, rules: {line-length: {max: 120}}}" --no-warnings
102102

103103
GOLANGCI_LINT = $(shell pwd)/bin/golangci-lint
@@ -171,3 +171,12 @@ test-spaces: ## Run the trailing spaces check
171171
test-legacy: ## Run the tests to validate legacy path for webhooks
172172
rm -rf ./testdata/**legacy**/
173173
./test/testdata/legacy-webhook-path.sh
174+
175+
.PHONY: install-helm
176+
install-helm: ## Install the latest version of Helm locally
177+
@curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
178+
179+
.PHONY: helm-lint
180+
helm-lint: install-helm ## Lint the Helm chart in testdata
181+
helm lint testdata/project-v4-multigroup/dist/chart
182+
helm lint testdata/project-v4-with-plugins/dist/chart

cmd/main.go

+2
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import (
3030
deployimagev1alpha1 "sigs.k8s.io/kubebuilder/v4/pkg/plugins/golang/deploy-image/v1alpha1"
3131
golangv4 "sigs.k8s.io/kubebuilder/v4/pkg/plugins/golang/v4"
3232
grafanav1alpha1 "sigs.k8s.io/kubebuilder/v4/pkg/plugins/optional/grafana/v1alpha"
33+
helmv1alpha1 "sigs.k8s.io/kubebuilder/v4/pkg/plugins/optional/helm/v1alpha"
3334
)
3435

3536
func init() {
@@ -61,6 +62,7 @@ func main() {
6162
&kustomizecommonv2.Plugin{},
6263
&deployimagev1alpha1.Plugin{},
6364
&grafanav1alpha1.Plugin{},
65+
&helmv1alpha1.Plugin{},
6466
),
6567
cli.WithPlugins(externalPlugins...),
6668
cli.WithDefaultPlugins(cfgv3.Version, gov4Bundle),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# Helm Plugin (`helm/v1-alpha`)
2+
3+
The Helm plugin is an optional plugin that can be used to scaffold a Helm chart, allowing you to distribute the project using Helm.
4+
5+
By default, users can generate a bundle with all the manifests by running the following command:
6+
7+
```bash
8+
make build-installer IMG=<some-registry>/<project-name:tag>
9+
```
10+
11+
This allows the project consumer to install the solution by applying the bundle with:
12+
13+
```bash
14+
kubectl apply -f https://raw.githubusercontent.com/<org>/project-v4/<tag or branch>/dist/install.yaml
15+
```
16+
17+
However, in many scenarios, you might prefer to provide a Helm chart to package your solution.
18+
If so, you can use this plugin to generate the Helm chart under the `dist` directory.
19+
20+
<aside class="note">
21+
<h1>Examples</h1>
22+
23+
You can check the plugin usage by looking at `project-v4-multigroup` and `project-v4-with-plugins` samples
24+
under the [testdata][testdata] directory on the root directory of the Kubebuilder project.
25+
26+
</aside>
27+
28+
## When to use it ?
29+
30+
- If you are looking to provide to your users a HelmChart to install and manage your project
31+
- If you want to update the HelmChart generated under `dist/chart/` with the latest changes
32+
33+
## How to use it ?
34+
35+
### Basic Usage
36+
37+
The Helm plugin is attached to the `init` subcommand and the `edit` subcommand:
38+
39+
```sh
40+
41+
# Initialize a new project with helm chart
42+
kubebuilder init --plugins=helm/v1-alpha
43+
44+
# Enable or Update the helm chart via the helm plugin to an existing project
45+
# Before run the edit command, run `make manifests` to generate the manifest under `config/`
46+
make manifests
47+
kubebuilder edit --plugins=helm/v1-alpha
48+
```
49+
<aside class="note">
50+
<h1>Use the edit command to update the Helm Chart with the latest changes</h1>
51+
52+
After making changes to your project, ensure that you run `make manifests` and then
53+
use the command `kubebuilder edit --plugins=helm/v1-alpha` to update the Helm Chart.
54+
55+
Note that the following files will **not** be updated unless you use the `--force=true` flag:
56+
57+
<pre>
58+
dist/chart/
59+
├── values.yaml
60+
├── .helmignore
61+
└── templates/
62+
├── _helpers.tpl
63+
└── manager/
64+
└── manager.yaml
65+
└── webhook/
66+
└── webhooks.yaml
67+
└── service.yaml
68+
</pre>
69+
70+
</aside>
71+
72+
## Subcommands
73+
74+
The Helm plugin implements the following subcommands:
75+
76+
- edit (`$ kubebuilder edit [OPTIONS]`)
77+
78+
- init (`$ kubebuilder init [OPTIONS]`)
79+
80+
## Affected files
81+
82+
The following scaffolds will be created or updated by this plugin:
83+
84+
- `dist/chart/*`
85+
86+
[testdata]: https://github.com/kubernetes-sigs/kubebuilder/tree/master/testdata/project-v4-with-plugins
87+

docs/book/src/plugins/to-add-optional-features.md

+7-5
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@
22

33
The following plugins are useful to generate code and take advantage of optional features
44

5-
| Plugin | Key | Description |
6-
|---------------------------------------------------| -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
7-
| [grafana.kubebuilder.io/v1-alpha][grafana] | `grafana/v1-alpha` | Optional helper plugin which can be used to scaffold Grafana Manifests Dashboards for the default metrics which are exported by controller-runtime. |
8-
| [deploy-image.go.kubebuilder.io/v1-alpha][deploy] | `deploy-image/v1-alpha` | Optional helper plugin which can be used to scaffold APIs and controller with code implementation to Deploy and Manage an Operand(image). |
5+
| Plugin | Key | Description |
6+
|---------------------------------------------------|-------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------|
7+
| [grafana.kubebuilder.io/v1-alpha][grafana] | `grafana/v1-alpha` | Optional helper plugin which can be used to scaffold Grafana Manifests Dashboards for the default metrics which are exported by controller-runtime. |
8+
| [deploy-image.go.kubebuilder.io/v1-alpha][deploy] | `deploy-image/v1-alpha` | Optional helper plugin which can be used to scaffold APIs and controller with code implementation to Deploy and Manage an Operand(image). |
9+
| [helm.kubebuilder.io/v1-alpha][helm] | `helm/v1-alpha` | Optional helper plugin which can be used to scaffold a Helm Chart to distribute the project under the `dist` directory |
910

1011
[grafana]: ./available/grafana-v1-alpha.md
11-
[deploy]: ./available/deploy-image-plugin-v1-alpha.md
12+
[deploy]: ./available/deploy-image-plugin-v1-alpha.md
13+
[helm]: ./available/helm-v1-alpha.md

pkg/cli/alpha/internal/generate.go

+36
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ const (
4444
defaultOutputDir = "output-dir"
4545
grafanaPluginKey = "grafana.kubebuilder.io/v1-alpha"
4646
deployImagePluginKey = "deploy-image.go.kubebuilder.io/v1-alpha"
47+
helmPluginKey = "helm.kubebuilder.io/v1-alpha"
4748
)
4849

4950
// Generate handles the migration and scaffolding process.
@@ -77,6 +78,12 @@ func (opts *Generate) Generate() error {
7778
return err
7879
}
7980

81+
if hasHelmPlugin(config) {
82+
if err := kubebuilderHelmEdit(); err != nil {
83+
return err
84+
}
85+
}
86+
8087
if err := migrateDeployImagePlugin(config); err != nil {
8188
return err
8289
}
@@ -392,3 +399,32 @@ func kubebuilderGrafanaEdit() error {
392399
}
393400
return nil
394401
}
402+
403+
// Edits the project to include the Grafana plugin.
404+
func kubebuilderHelmEdit() error {
405+
args := []string{"edit", "--plugins", helmPluginKey}
406+
if err := util.RunCmd("kubebuilder edit", "kubebuilder", args...); err != nil {
407+
return fmt.Errorf("failed to run edit subcommand for Helm plugin: %w", err)
408+
}
409+
return nil
410+
}
411+
412+
// hasHelmPlugin checks if the Helm plugin is present by inspecting the plugin chain or configuration.
413+
func hasHelmPlugin(cfg store.Store) bool {
414+
var pluginConfig map[string]interface{}
415+
416+
// Decode the Helm plugin configuration to check if it's present
417+
err := cfg.Config().DecodePluginConfig(helmPluginKey, &pluginConfig)
418+
if err != nil {
419+
// If the Helm plugin is not found, return false
420+
if errors.As(err, &config.PluginKeyNotFoundError{}) {
421+
return false
422+
}
423+
// Log other errors if needed
424+
log.Errorf("Error decoding Helm plugin config: %v", err)
425+
return false
426+
}
427+
428+
// Helm plugin is present
429+
return true
430+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
Copyright 2024 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+
package v1alpha
18+
19+
import (
20+
"errors"
21+
22+
"sigs.k8s.io/kubebuilder/v4/pkg/config"
23+
)
24+
25+
func insertPluginMetaToConfig(target config.Config, cfg pluginConfig) error {
26+
err := target.DecodePluginConfig(pluginKey, cfg)
27+
if !errors.As(err, &config.UnsupportedFieldError{}) {
28+
if err != nil && !errors.As(err, &config.PluginKeyNotFoundError{}) {
29+
return err
30+
}
31+
if err = target.EncodePluginConfig(pluginKey, cfg); err != nil {
32+
return err
33+
}
34+
}
35+
36+
return nil
37+
}

0 commit comments

Comments
 (0)