Skip to content

Validate files generated by your templates

HAProxy checks its own configuration, but your templates may also generate files for another service. A custom validator checks those files and rejects invalid output before HAPTIC deploys it.

The chart already configures a validator for the SPOA hub when the hub is enabled. Use the settings below when you need to validate another file format or supply your own validator implementation. Implementations follow the validator wire protocol.

Default chart setup

The chart enables the bundled validator whenever a SPOA hub plugin is enabled. Leave controller.validators.enabled at its default null for this automatic selection. You don't need to configure sockets or file patterns for the bundled plugins.

A validator can accept a file, return a warning, or reject it. A rejection stops new output from being published or deployed and denies the corresponding admission request. HAProxy keeps its last working configuration. HAProxy syntax is checked separately with haproxy -c.

Configuration

Declare validators on HAProxyTemplateConfig

The following is a configuration fragment. With Helm, use controller.validators.entries, as shown in custom validators.

apiVersion: haproxy-haptic.org/v1alpha1
kind: HAProxyTemplateConfig
metadata:
  name: example
spec:
  # ... other fields ...
  validators:
    - name: spoa-hub
      socketPath: /var/run/haptic-validators/spoa-hub.sock
      files:
        - "general/spoa-hub-config.toml"
      timeoutMs: 5000
      maxConnections: 4
Field Required Description
name yes Unique RFC 1123 label. Appears in validation logs.
socketPath yes Absolute path inside the controller pod to the validator's Unix domain socket. The chart-rendered shared emptyDir mounts at /var/run/haptic-validators/.
files yes List of glob patterns matched against rendered file paths to decide which files to send to this validator. Patterns follow Go's path/filepath.Match rules and must use the same relative or absolute form as the rendered path. Malformed patterns are rejected during config validation. At least one entry is required.
dataFiles no Glob patterns for supporting files supplied with every validation request. These files aren't validated individually. A file matching both files and dataFiles is treated as supporting data.
timeoutMs no Deadline per file in milliseconds, including connection wait and response. Default: 5000. Range: 1–60000.
maxConnections no Cap on the controller's connection pool to this validator. Defaults to 4. Range: 1–32. Connections open on demand and close after an idle period.

Routing examples

A files pattern of general/spoa-hub-config.toml selects generated TOML files in general storage. A file can match more than one validator; all matching validators must accept it before deployment. A file that matches none isn't checked by a sidecar, even if HAProxy accepts the configuration that refers to it.

Operations

Three-result behaviour

Validators return one of three outcomes per file. The pipeline maps them as follows:

Validator result Pipeline outcome Admission outcome
valid Continue Admission completes normally.
warning Continue and record the warning count kubectl apply prints each warning as a soft warning.
error Stop before publication or deployment kubectl apply prints the formatted errors and rejects the resource.

Any validator error blocks deployment. Warnings alone don't block it.

/healthz integration

The controller reports HTTP 503 when a configured validator socket is missing or unreachable. Check the validator container's state and logs, then verify that its socket path matches the declaration. The controller and validator containers restart independently.

Validation runs for every applicable change, including unchanged file contents. maxConnections controls how many requests one validator can handle at once; raising it doesn't speed up a single slow file check.

Failure modes

Symptom What to check
Socket missing or connection refused Validator container status, volume mounts, and socketPath.
File rejected The reported file, row, and column; fix the template or input that produced it.
Validation timeout Validator CPU, memory, and logs. Increase timeoutMs only if a valid file needs more time.
Protocol error The validator image's compatibility with the wire protocol.
Warning in kubectl apply The resource is accepted; read the warning for any remaining action.

Custom validators

Add your validator beside the bundled validator. It must implement the validator wire protocol and listen on a Unix socket shared with the controller.

Merge this example into your complete Helm values. Replace the example image with your validator image and select the paths your templates generate:

controller:
  validators:
    entries:
      - name: my-validator
        socketPath: /var/run/my-validator/validator.sock
        files: ["general/my-app-*.yaml"]
  sidecars:
    - name: my-validator
      image: registry.example.com/my-validator:v1.2.3
      args: ["--validate-socket", "/var/run/my-validator/validator.sock"]
      volumeMounts:
        - name: my-validator-socket
          mountPath: /var/run/my-validator
  extraVolumeMounts:
    - name: my-validator-socket
      mountPath: /var/run/my-validator
  extraVolumes:
    - name: my-validator-socket
      emptyDir: {}

Keep any existing sidecars, mounts, and volumes when editing these lists: Helm replaces lists. The custom entry is added to the bundled validators. Use a unique name; overriding an existing name replaces that validator's declaration.

Troubleshooting

Inspect controller logs and the custom sidecar logs for the default haptic release and the my-validator container from the example:

kubectl logs deployment/haptic-controller --namespace haptic --container controller --tail=100
kubectl logs deployment/haptic-controller --namespace haptic --container my-validator --tail=100

If the sidecar is repeatedly restarted, inspect its previous logs and pod events for an out-of-memory termination or failed mount. Restore the validator before retrying the rejected change; disabling validation would leave its files unchecked.

See also

Found a problem on this page? Report it