Skip to content

Commit 016caa2

Browse files
committed
feat: add helm kcl template alpha command.
1 parent 3da1aff commit 016caa2

26 files changed

+1570
-4
lines changed

README.md

+31
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,31 @@ You can use the `Helm-KCL-Plugin` to
1313
+ For multi-environment and multi-tenant scenarios, you can maintain these configurations gracefully rather than simply copy and paste.
1414
+ Validate all KRM resources using the KCL schema.
1515

16+
## Prerequisites
17+
18+
+ Install Helm
19+
+ Golang (at least version 1.18)
20+
21+
## Test the Plugin
22+
23+
You need to put your KCL script source in the functionConfig of kind KCLRun and then the function will run the KCL script that you provide.
24+
25+
```bash
26+
# Verify that the annotation is added to the `Deployment` resource and the other resource `Service`
27+
# does not have this annotation.
28+
diff \
29+
<(helm template ./examples/workload-charts-with-kcl/workload-charts) \
30+
<(go run main.go template --file ./examples/workload-charts-with-kcl/kcl-run.yaml) |\
31+
grep annotations -A1
32+
```
33+
34+
The output is
35+
36+
```diff
37+
> annotations:
38+
> managed-by: helm-kcl-plugin
39+
```
40+
1641
## Install
1742

1843
### Using Helm plugin manager (> 2.3.x)
@@ -63,6 +88,12 @@ make install
6388
make install/helm3
6489
```
6590

91+
## Quick Start
92+
93+
```shell
94+
helm create my-chart
95+
```
96+
6697
## Build
6798

6899
### Prerequisites

cmd/root.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,11 @@ func New() *cobra.Command {
1616
Use: "kcl",
1717
Short: "Edit, transformer, validate Helm charts using the KCL programming language.",
1818
Long: rootCmdLongUsage,
19+
SilenceUsage: true,
1920
}
2021

21-
cmd.AddCommand(newVersionCmd())
22+
cmd.AddCommand(NewVersionCmd())
23+
cmd.AddCommand(NewTemplateCmd())
2224
cmd.SetHelpCommand(&cobra.Command{}) // Disable the help command
2325
return cmd
2426
}

cmd/template.go

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package cmd
2+
3+
import (
4+
"github.com/spf13/cobra"
5+
6+
"kusionstack.io/helm-kcl/pkg/app"
7+
"kusionstack.io/helm-kcl/pkg/config"
8+
)
9+
10+
// NewTemplateCmd returm template subcmd
11+
func NewTemplateCmd() *cobra.Command {
12+
templateOptions := config.NewTemplateOptions()
13+
14+
cmd := &cobra.Command{
15+
Use: "template",
16+
Short: "Template releases defined in the KCL state file",
17+
PreRun: func(*cobra.Command, []string) {
18+
app.ExpandTLSPaths()
19+
},
20+
RunE: func(*cobra.Command, []string) error {
21+
err := app.New().Template(config.NewTemplateImpl(templateOptions))
22+
if err != nil {
23+
return err
24+
}
25+
return nil
26+
},
27+
SilenceUsage: true,
28+
}
29+
30+
f := cmd.Flags()
31+
f.StringVar(&templateOptions.File, "file", "", "input kcl file to pass to helm kcl template")
32+
f.StringArrayVar(&templateOptions.Set, "set", nil, "additional values to be merged into the helm command --set flag")
33+
f.StringArrayVar(&templateOptions.Values, "values", nil, "additional value files to be merged into the helm command --values flag")
34+
f.StringVar(&templateOptions.OutputDir, "output-dir", "", "output directory to pass to helm template (helm template --output-dir)")
35+
f.StringVar(&templateOptions.OutputDirTemplate, "output-dir-template", "", "go text template for generating the output directory. Default: {{ .OutputDir }}/{{ .State.BaseName }}-{{ .State.AbsPathSHA1 }}-{{ .Release.Name}}")
36+
f.IntVar(&templateOptions.Concurrency, "concurrency", 0, "maximum number of concurrent helm processes to run, 0 is unlimited")
37+
f.BoolVar(&templateOptions.Validate, "validate", false, "validate your manifests against the Kubernetes cluster you are currently pointing at. Note that this requires access to a Kubernetes cluster to obtain information necessary for validating, like the template of available API versions")
38+
f.BoolVar(&templateOptions.IncludeCRDs, "include-crds", false, "include CRDs in the templated output")
39+
f.BoolVar(&templateOptions.SkipTests, "skip-tests", false, "skip tests from templated output")
40+
f.BoolVar(&templateOptions.SkipNeeds, "skip-needs", true, `do not automatically include releases from the target release's "needs" when --selector/-l flag is provided. Does nothing when --selector/-l flag is not provided. Defaults to true when --include-needs or --include-transitive-needs is not provided`)
41+
f.BoolVar(&templateOptions.IncludeNeeds, "include-needs", false, `automatically include releases from the target release's "needs" when --selector/-l flag is provided. Does nothing when --selector/-l flag is not provided`)
42+
f.BoolVar(&templateOptions.IncludeTransitiveNeeds, "include-transitive-needs", false, `like --include-needs, but also includes transitive needs (needs of needs). Does nothing when --selector/-l flag is not provided. Overrides exclusions of other selectors and conditions.`)
43+
f.BoolVar(&templateOptions.SkipDeps, "skip-deps", false, `skip running "helm repo update" and "helm dependency build"`)
44+
f.BoolVar(&templateOptions.SkipCleanup, "skip-cleanup", false, "Stop cleaning up temporary values generated by helmfile and helm-secrets. Useful for debugging. Don't use in production for security")
45+
f.StringVar(&templateOptions.PostRenderer, "post-renderer", "", `pass --post-renderer to "helm template" or "helm upgrade --install"`)
46+
47+
if !app.IsHelm3() {
48+
app.AddCommonCmdOptions(f)
49+
}
50+
51+
return cmd
52+
}

cmd/version.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,13 @@ import (
99
// Version identifier populated via the CI/CD process.
1010
var Version = "HEAD"
1111

12-
func newVersionCmd() *cobra.Command {
12+
func NewVersionCmd() *cobra.Command {
1313
return &cobra.Command{
1414
Use: "version",
1515
Short: "Show version of the helm kcl plugin",
1616
Run: func(*cobra.Command, []string) {
1717
fmt.Println(Version)
1818
},
19+
SilenceUsage: true,
1920
}
2021
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# kcl-config.yaml
2+
apiVersion: fn.kpt.dev/v1alpha1
3+
kind: KCLRun
4+
metadata:
5+
name: set-annotation
6+
# EDIT THE SOURCE!
7+
# This should be your KCL code which preloads the `ResourceList` to `option("resource_list")
8+
source: |
9+
[resource | {if resource.kind == "Deployment": metadata.annotations: {"managed-by" = "helm-kcl-plugin"}} for resource in option("resource_list").items]
10+
11+
repositories:
12+
- name: workload
13+
path: ./workload-charts
14+
# TDDO:
15+
# url
16+
# git
17+
# oci
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Patterns to ignore when building packages.
2+
# This supports shell glob matching, relative path matching, and
3+
# negation (prefixed with !). Only one pattern per line.
4+
.DS_Store
5+
# Common VCS dirs
6+
.git/
7+
.gitignore
8+
.bzr/
9+
.bzrignore
10+
.hg/
11+
.hgignore
12+
.svn/
13+
# Common backup files
14+
*.swp
15+
*.bak
16+
*.tmp
17+
*.orig
18+
*~
19+
# Various IDEs
20+
.project
21+
.idea/
22+
*.tmproj
23+
.vscode/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
apiVersion: v2
2+
appVersion: 0.1.0
3+
description: A helm chart to provision standard workloads.
4+
name: workload
5+
type: application
6+
version: 0.1.0
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
{{/*
2+
Expand the name of the chart.
3+
*/}}
4+
{{- define "workload.name" -}}
5+
{{- default .Release.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
6+
{{- end }}
7+
{{/*
8+
Create a default fully qualified app name.
9+
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
10+
If release name contains chart name it will be used as a full name.
11+
*/}}
12+
{{- define "workload.fullname" -}}
13+
{{- $name := default .Chart.Name .Values.nameOverride }}
14+
{{- if contains $name .Release.Name }}
15+
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
16+
{{- else }}
17+
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
18+
{{- end }}
19+
{{- end }}
20+
{{/*
21+
Create chart name and version as used by the chart label.
22+
*/}}
23+
{{- define "workload.chart" -}}
24+
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
25+
{{- end }}
26+
{{/*
27+
Common labels
28+
*/}}
29+
{{- define "workload.labels" -}}
30+
helm.sh/chart: {{ include "workload.chart" . }}
31+
{{ include "workload.selectorLabels" . }}
32+
{{- if .Chart.AppVersion }}
33+
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
34+
{{- end }}
35+
app.kubernetes.io/managed-by: {{ .Release.Service }}
36+
{{- end }}
37+
{{/*
38+
Selector labels
39+
*/}}
40+
{{- define "workload.selectorLabels" -}}
41+
app.kubernetes.io/name: {{ include "workload.name" . }}
42+
app.kubernetes.io/instance: {{ .Release.Name }}
43+
{{- end }}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
apiVersion: apps/v1
2+
kind: Deployment
3+
metadata:
4+
name: {{ include "workload.name" . }}
5+
labels:
6+
{{- include "workload.labels" . | nindent 4 }}
7+
spec:
8+
selector:
9+
matchLabels:
10+
{{- include "workload.selectorLabels" . | nindent 6 }}
11+
template:
12+
metadata:
13+
labels:
14+
{{- include "workload.selectorLabels" . | nindent 8 }}
15+
spec:
16+
containers:
17+
{{- range $name, $container := .Values.containers }}
18+
- name: {{ $name }}
19+
image: "{{ $container.image.name }}"
20+
{{- with $container.command }}
21+
command:
22+
{{- toYaml $container.command | nindent 12 }}
23+
{{- end }}
24+
{{- with $container.args }}
25+
args:
26+
{{- toYaml $container.args | nindent 12 }}
27+
{{- end }}
28+
{{- with $container.env }}
29+
env:
30+
{{- toYaml $container.env | nindent 12 }}
31+
{{- end }}
32+
{{- with $container.volumeMounts }}
33+
volumeMounts:
34+
{{- toYaml $container.volumeMounts | nindent 12 }}
35+
{{- end }}
36+
{{- with $container.livenessProbe }}
37+
livenessProbe:
38+
{{- toYaml $container.livenessProbe | nindent 12 }}
39+
{{- end }}
40+
{{- with $container.readinessProbe }}
41+
readinessProbe:
42+
{{- toYaml $container.readinessProbe | nindent 12 }}
43+
{{- end }}
44+
{{- with $container.resources }}
45+
resources:
46+
{{- toYaml $container.resources | nindent 12 }}
47+
{{- end }}
48+
{{- end }}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{{ if .Values.service }}
2+
apiVersion: v1
3+
kind: Service
4+
metadata:
5+
name: {{ include "workload.name" . }}
6+
labels:
7+
{{- include "workload.labels" . | nindent 4 }}
8+
spec:
9+
type: {{ .Values.service.type }}
10+
selector:
11+
{{- include "workload.selectorLabels" . | nindent 4 }}
12+
{{- with .Values.service.ports }}
13+
ports:
14+
{{- toYaml . | nindent 4 }}
15+
{{- end }}
16+
{{- end }}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#
2+
# Default values for the chart (for reference only).
3+
# An actual values file is rendered from the source SCORE file by the CLI tool.
4+
5+
containers:
6+
frontend:
7+
image:
8+
name: nginx:alpine
9+
10+
service:
11+
type: ClusterIP
12+
ports:
13+
- name: www
14+
protocol: TCP
15+
port: 80
16+
targetPort: 80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
---
2+
# Source: workload/templates/deployment.yaml
3+
apiVersion: apps/v1
4+
kind: Deployment
5+
metadata:
6+
name: release-name
7+
labels:
8+
helm.sh/chart: workload-0.1.0
9+
app.kubernetes.io/name: release-name
10+
app.kubernetes.io/instance: release-name
11+
app.kubernetes.io/version: "0.1.0"
12+
app.kubernetes.io/managed-by: Helm
13+
spec:
14+
selector:
15+
matchLabels:
16+
app.kubernetes.io/name: release-name
17+
app.kubernetes.io/instance: release-name
18+
template:
19+
metadata:
20+
labels:
21+
app.kubernetes.io/name: release-name
22+
app.kubernetes.io/instance: release-name
23+
spec:
24+
containers:
25+
- name: frontend
26+
image: "nginx:alpine"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
---
2+
# Source: workload/templates/service.yaml
3+
apiVersion: v1
4+
kind: Service
5+
metadata:
6+
name: release-name
7+
labels:
8+
helm.sh/chart: workload-0.1.0
9+
app.kubernetes.io/name: release-name
10+
app.kubernetes.io/instance: release-name
11+
app.kubernetes.io/version: "0.1.0"
12+
app.kubernetes.io/managed-by: Helm
13+
spec:
14+
type: ClusterIP
15+
selector:
16+
app.kubernetes.io/name: release-name
17+
app.kubernetes.io/instance: release-name
18+
ports:
19+
- name: www
20+
port: 80
21+
protocol: TCP
22+
targetPort: 80

0 commit comments

Comments
 (0)