Documentation
¶
Overview ¶
Package validation provides shared validation utilities for BubuStack resources.
This package contains validation helpers used by controllers and webhooks, including error aggregation, reason extraction, and JSON schema validation.
Error Aggregation ¶
The Aggregator collects multiple validation errors for bulk status updates:
agg := validation.NewAggregator()
agg.AddFieldError("spec.steps[0].ref", conditions.ReasonEngramReferenceInvalid, "engram not found")
agg.AddFieldError("spec.steps[1].transport", conditions.ReasonTransportReferenceInvalid, "transport not found")
if agg.HasErrors() {
return nil, agg.ToFieldErrors() // For webhooks
// OR
result := agg.ToValidationResult("success") // For controllers
}
Reason Errors ¶
The WrapWithReason function attaches a structured reason to an error:
err := validation.WrapWithReason(conditions.ReasonTemplateNotFound, fmt.Errorf("template not found"))
reason := validation.ExtractReason(err) // Returns conditions.ReasonTemplateNotFound
JSON Schema Validation ¶
The ValidateJSONSchema function validates that bytes represent valid JSON:
if err := validation.ValidateJSONSchema(schemaBytes); err != nil {
return fmt.Errorf("invalid schema: %w", err)
}
This package is designed for use in admission webhooks and controller reconcile loops that need to collect and report multiple validation errors.
Package validation provides shared validation helpers for controllers and webhooks.
Package validation provides shared validation utilities used across the codebase.
Index ¶
- func ExtractReason(err error) string
- func ValidateJSONSchema(schemaBytes []byte) error
- func WrapWithReason(reason string, err error) error
- type Aggregator
- func (a *Aggregator) Add(err *ValidationError)
- func (a *Aggregator) AddError(err error)
- func (a *Aggregator) AddFieldError(fieldName, reason, message string)
- func (a *Aggregator) AddFieldErrorf(fieldName, reason, format string, args ...any)
- func (a *Aggregator) CombinedMessage() string
- func (a *Aggregator) Errors() []*ValidationError
- func (a *Aggregator) FirstError() error
- func (a *Aggregator) FirstReason() string
- func (a *Aggregator) HasErrors() bool
- func (a *Aggregator) Messages() []string
- func (a *Aggregator) ToFieldErrors() field.ErrorList
- func (a *Aggregator) ToValidationResult(successMessage string) *ValidationResult
- type ReasonError
- type ValidationError
- type ValidationResult
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ExtractReason ¶
ExtractReason extracts the reason string from a validation error.
Behavior:
- Returns the reason from *ReasonError if present.
- Falls back to substring heuristics (engram/transport/story).
- Defaults to conditions.ReasonReferenceNotFound when no signal is found.
Arguments:
- err error: the validation error to analyze.
Returns:
- string: the event reason string for Kubernetes events.
func ValidateJSONSchema ¶
ValidateJSONSchema performs basic JSON schema validation by attempting to unmarshal the provided bytes as JSON, ensuring the schema is syntactically valid.
Arguments:
- schemaBytes: raw JSON bytes representing a JSON schema.
Returns:
- error: nil if the JSON is valid, or an error describing the validation failure.
func WrapWithReason ¶
WrapWithReason attaches a structured reason to a validation error so event emitters can extract consistent Kubernetes event reasons.
Behavior:
- Returns nil when err is nil (nil-safe).
- Wraps the error with a reason that can be extracted via errors.As.
- Preserves original error via Unwrap for errors.Is/errors.As chains.
Arguments:
- reason string: the event reason to attach (e.g., conditions.ReasonEngramReferenceInvalid).
- err error: the underlying validation error.
Returns:
- error: nil when err is nil, otherwise a *ReasonError.
Types ¶
type Aggregator ¶
type Aggregator struct {
// contains filtered or unexported fields
}
Aggregator collects multiple validation errors for bulk status updates.
Behavior:
- Collects errors without stopping on the first failure.
- Converts collected errors to field.ErrorList for webhook responses.
- Converts collected errors to condition/status for controller status.
- Thread-safe for single-goroutine use within a reconcile loop.
Usage (controller):
agg := validation.NewAggregator()
agg.AddFieldError("spec.steps[0].ref", conditions.ReasonEngramReferenceInvalid, "engram not found")
agg.AddFieldError("spec.steps[1].transport", conditions.ReasonTransportReferenceInvalid, "transport not found")
if agg.HasErrors() {
status := agg.ToStatus()
}
Usage (webhook):
agg := validation.NewAggregator()
agg.AddFieldError("spec.steps[0].ref", conditions.ReasonEngramReferenceInvalid, "engram not found")
if agg.HasErrors() {
return nil, agg.ToFieldErrors()
}
func NewAggregator ¶
func NewAggregator() *Aggregator
NewAggregator creates a new validation error aggregator.
func (*Aggregator) Add ¶
func (a *Aggregator) Add(err *ValidationError)
Add adds an existing ValidationError to the aggregator.
func (*Aggregator) AddError ¶
func (a *Aggregator) AddError(err error)
AddError wraps a generic error and adds it to the aggregator.
Behavior:
- Extracts reason from *ReasonError if present.
- Falls back to ExtractReason heuristics if not.
func (*Aggregator) AddFieldError ¶
func (a *Aggregator) AddFieldError(fieldName, reason, message string)
AddFieldError adds a validation error with field path, reason, and message.
func (*Aggregator) AddFieldErrorf ¶
func (a *Aggregator) AddFieldErrorf(fieldName, reason, format string, args ...any)
AddFieldErrorf adds a validation error with formatted message.
func (*Aggregator) CombinedMessage ¶
func (a *Aggregator) CombinedMessage() string
CombinedMessage returns all error messages joined by semicolons.
func (*Aggregator) Errors ¶
func (a *Aggregator) Errors() []*ValidationError
Errors returns the collected validation errors.
func (*Aggregator) FirstError ¶
func (a *Aggregator) FirstError() error
FirstError returns the first error, or nil if empty.
func (*Aggregator) FirstReason ¶
func (a *Aggregator) FirstReason() string
FirstReason returns the reason of the first error, or ReasonReferenceNotFound if empty.
func (*Aggregator) HasErrors ¶
func (a *Aggregator) HasErrors() bool
HasErrors returns true if any validation errors were collected.
func (*Aggregator) Messages ¶
func (a *Aggregator) Messages() []string
Messages returns all error messages as a slice.
func (*Aggregator) ToFieldErrors ¶
func (a *Aggregator) ToFieldErrors() field.ErrorList
ToFieldErrors converts collected errors to field.ErrorList for webhook responses.
Behavior:
- Creates a field.Error for each ValidationError with Type=Invalid.
- Uses the field path if provided, otherwise uses an empty path.
func (*Aggregator) ToValidationResult ¶
func (a *Aggregator) ToValidationResult(successMessage string) *ValidationResult
ToValidationResult converts collected errors to a ValidationResult for status updates.
Behavior:
- Returns Valid status when no errors.
- Returns Invalid status with aggregated messages when errors exist.
- Uses the first error's reason for the condition reason.
Arguments:
- successMessage string: the message to use when validation passes.
type ReasonError ¶
type ReasonError struct {
// contains filtered or unexported fields
}
ReasonError wraps an error with a structured reason string so callers can emit consistent Kubernetes event reasons while preserving the original error.
Behavior:
- Error() returns the underlying error message.
- Unwrap() returns the underlying error for errors.Is/errors.As chains.
- Reason() returns the structured reason string.
Usage:
err := validation.WrapWithReason(conditions.ReasonEngramReferenceInvalid, originalErr)
var reasonErr *validation.ReasonError
if errors.As(err, &reasonErr) {
fmt.Println(reasonErr.Reason()) // "EngramReferenceInvalid"
}
func (*ReasonError) Error ¶
func (e *ReasonError) Error() string
Error satisfies the error interface by returning the wrapped error's message.
func (*ReasonError) Reason ¶
func (e *ReasonError) Reason() string
Reason returns the structured reason string for Kubernetes events.
func (*ReasonError) Unwrap ¶
func (e *ReasonError) Unwrap() error
Unwrap returns the underlying error for errors.Is/errors.As traversal.
type ValidationError ¶
type ValidationError struct {
// Field is the path to the invalid field (e.g., "spec.steps[3].ref").
Field string
// Reason is the event reason code (e.g., conditions.ReasonEngramReferenceInvalid).
Reason string
// Message is the human-readable error message.
Message string
// Err is the underlying error (may be nil).
Err error
}
ValidationError represents a single validation error with field path and reason.
Behavior:
- Captures the field path (e.g., "spec.steps[3].ref") for precise error location.
- Includes a structured reason for Kubernetes events.
- Provides a human-readable message for users.
func (*ValidationError) Error ¶
func (e *ValidationError) Error() string
Error implements the error interface.
func (*ValidationError) Unwrap ¶
func (e *ValidationError) Unwrap() error
Unwrap returns the underlying error for errors.Is/errors.As.
type ValidationResult ¶
type ValidationResult struct {
// ValidationStatus is Valid when no errors, Invalid otherwise.
ValidationStatus enums.ValidationStatus
// ValidationErrors contains all error messages.
ValidationErrors []string
// ConditionStatus is the status for the Ready condition.
ConditionStatus metav1.ConditionStatus
// ConditionReason is the reason for the Ready condition.
ConditionReason string
// ConditionMessage is the message for the Ready condition.
ConditionMessage string
}
ValidationResult holds the outcome of validation for controller status updates.