name: nic-add-feature description: 'Checklists for adding Ingress annotations, VirtualServer/VSR fields, or Helm chart values to NIC. Use when adding new configuration options, new NGINX directives, new annotations, new CRD fields, or new Helm values.'
Adding Features to NIC
Adding a New Annotation (Ingress Only)
Annotations apply ONLY to Ingress objects, never to VirtualServer or VirtualServerRoute.
- Add constant in
internal/configs/annotations.go(e.g.,MyAnnotation = "nginx.org/my-annotation") - Add field to
ConfigParamsininternal/configs/config_params.go - Parse it in
parseAnnotations()ininternal/configs/annotations.go - Update
masterDenylist/minionDenylistif it should not be on master/minion - Apply it in
generateNginxCfg()ininternal/configs/ingress.go - Add the NGINX directive in
internal/configs/version1/nginx.ingress.tmplandinternal/configs/version1/nginx-plus.ingress.tmpl - Add validation in
internal/k8s/validation.goannotation validation chains - Add tests in
annotations_test.goandingress_test.go
Gotchas
- Never forget both OSS and Plus templates -- they are separate files
- Use
containsDangerousChars()for any user-provided string that ends up in NGINX config parseAnnotations()silently ignores unknown annotations -- add the constant first
Adding a New VirtualServer/VSR Field
- Add field to the appropriate struct in
pkg/apis/configuration/v1/types.gowith kubebuilder markers - Run
make update-codegenandmake update-crds - Add validation in
pkg/apis/configuration/validation/virtualserver.go - Add to the version2 template struct in
internal/configs/version2/http.go - Wire in
internal/configs/virtualserver.go(GenerateVirtualServerConfigor helper) - Add template rendering in
nginx.virtualserver.tmpl/nginx-plus.virtualserver.tmpl - Update snapshot tests and run
make test-update-snaps
JSON Tag Conventions
- NGINX-proxy-related fields: kebab-case (
json:"lb-method",json:"fail-timeout") - K8s/application fields: camelCase (
json:"ingressClassName",json:"rewritePath")
Pointer vs Value Types
*int,*bool,*SomeStruct= optional/nullable- Plain
int,bool= required or zero-value default - Booleans defaulting to
falsemust be non-pointer
Kubebuilder Markers
| Marker | Purpose |
|---|---|
+kubebuilder:validation:Required |
Field must be present |
+kubebuilder:validation:Optional |
Field is optional |
+kubebuilder:validation:Pattern= `regex` |
Regex validation |
+kubebuilder:validation:Minimum=N |
Numeric minimum |
+kubebuilder:validation:MinItems=N / MaxItems=N |
Array length |
+kubebuilder:validation:MaxLength=N |
Max string length |
+kubebuilder:default=value |
Default value |
+kubebuilder:validation:XValidation:rule="CEL" |
Cross-field CEL validation |
CEL Validation Examples
// Prevent wildcard origin with credentials
// +kubebuilder:validation:XValidation:rule="!(self.allowOrigin.exists(origin, origin == '*') && has(self.allowCredentials) && self.allowCredentials == true)",message="..."
// Require time when allowedCodes is set
// +kubebuilder:validation:XValidation:rule="!has(self.allowedCodes) || (has(self.allowedCodes) && has(self.time))",message="..."
Gotchas
- Never skip
make update-codegenafter changingtypes.go - Never edit
zz_generated.deepcopy.gomanually - Version 2 has a single
Serverblock; Version 1 has multipleServerblocks
Adding a Helm Chart Value
- Add to
charts/nginx-ingress/values.yamlwith##documentation above the field - Add JSON schema in
charts/nginx-ingress/values.schema.json - If it maps to a CLI arg: add to
nginx-ingress.argsincharts/nginx-ingress/templates/_helpers.tpl - If it maps to a ConfigMap key: add to
charts/nginx-ingress/templates/controller-configmap.yaml - If it needs volumes/mounts: add to the volume helpers in
_helpers.tpl - Create a testdata file in
charts/tests/testdata/<feature>.yaml - Add test case in
charts/tests/helmunit_test.go - Run
make test-update-snapsto capture the new snapshot
Gotchas
- Always update all three workload templates (deployment, daemonset, statefulset) when they share logic via helpers
- Always update
values.schema.jsonalongsidevalues.yaml - Helm tests use terratest + go-snaps:
charts/tests/helmunit_test.go