# 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`)

## Why This Tool?

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

```bash
# 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) |

## Output Format

For single-flag CRDs:

```yaml
{{- 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):

```yaml
{{- 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:

```yaml
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`:

```go
var crdFeatureFlags = map[string][]string{
    "newcrdtype": {"newFeature"},
    // For shared CRDs:
    "sharedcrd": {"server", "newFeature"},
}
```

Then add the corresponding value to `values.yaml`.
