CRD Helm Wrapper
A Go tool that wraps Kubernetes CRD YAML files with Helm template conditionals for:
- Feature flags (
crds.install.server, crds.install.registry, crds.install.virtualMcp)
- Resource policy annotations (
crds.keep → helm.sh/resource-policy: keep)
Helm does not upgrade CRDs during helm upgrade operations. CRDs placed in the crds/ directory are only processed during initial installation. By placing CRDs in templates/ with conditionals, they are upgraded alongside the chart.
Raw CRDs generated by controller-gen don't have Helm templating. This tool wraps them with conditionals so users can:
- Enable/disable specific CRD groups via feature flags
- Prevent Helm from deleting CRDs on uninstall
Usage
# Run the tool
go run main.go \
-source ../files/crds \
-target ../templates \
-verbose
Flags
| Flag |
Description |
Required |
-source |
Source directory containing raw CRD YAML files |
Yes |
-target |
Target directory for wrapped Helm templates |
Yes |
-verbose |
Enable verbose output |
No |
Feature Flag Groups
CRDs are grouped by feature flags. Some CRDs belong to multiple groups:
| Flag |
CRDs |
crds.install.server |
mcpservers, mcpremoteproxies, mcptoolconfigs, mcpgroups |
crds.install.registry |
mcpregistries |
crds.install.virtualMcp |
virtualmcpservers, virtualmcpcompositetooldefinitions |
crds.install.server OR crds.install.virtualMcp |
mcpexternalauthconfigs (shared) |
For single-flag CRDs:
{{- if .Values.crds.install.server }}
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
{{- if .Values.crds.keep }}
helm.sh/resource-policy: keep
{{- end }}
controller-gen.kubebuilder.io/version: v0.17.3
name: mcpservers.toolhive.stacklok.dev
spec:
...
{{- end }}
For shared CRDs (multiple groups):
{{- if or .Values.crds.install.server .Values.crds.install.virtualMcp }}
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
{{- if .Values.crds.keep }}
helm.sh/resource-policy: keep
{{- end }}
controller-gen.kubebuilder.io/version: v0.17.3
name: mcpexternalauthconfigs.toolhive.stacklok.dev
spec:
...
{{- end }}
Values Configuration
The wrapped CRDs expect these values:
crds:
# Whether to add the "helm.sh/resource-policy: keep" annotation
keep: true
# Feature flags for CRD groups
install:
server: true
registry: true
virtualMcp: true
Template Escaping
CRD descriptions may contain Go template-like syntax (e.g., {{.steps.step_id.output}}). The tool automatically escapes these to prevent Helm from interpreting them as template directives.
Template Files
The tool uses embedded template files in the templates/ directory:
| File |
Purpose |
header.tpl |
Opening conditional with __FEATURE_CONDITION__ placeholder |
footer.tpl |
Closing {{- end }} |
keep-annotation.tpl |
Conditional helm.sh/resource-policy: keep annotation |
Adding New CRD Groups
To add a new feature flag group, update the crdFeatureFlags map in main.go:
var crdFeatureFlags = map[string][]string{
"newcrdtype": {"newFeature"},
// For shared CRDs:
"sharedcrd": {"server", "newFeature"},
}
Then add the corresponding value to values.yaml.