package validate import ( "errors" "fmt" "strings" wh "edge-infra.dev/pkg/f8n/warehouse" ) // Annotation errors var ( errEmptyAnnotation = errors.New("must be non-empty") errMissingAnnotation = errors.New("must be specified") errInvalidURLAnnotation = errors.New("must be valid URL") errInvalidVersionAnnotation = errors.New("must be valid SemVer version") errInvalidTimestampAnnotation = errors.New("must be valid RFC3339 timestamp") errInvalidBinaryAnnotation = errors.New("must be 'true' or 'false'") errInvalidListAnnotation = fmt.Errorf("must be comma separated list matching %s", csvListRegex) errInvalidRevisionAnnotation = fmt.Errorf("must be valid revision hash matching %s", revisionHashRegex) errInvalidSchemaAnnotation = fmt.Errorf("must be '%s'", wh.Schema1) ) // Pallet specific errors var ( errInvalidPalletKindAnnotation = fmt.Errorf("must be '%s'", wh.PalletKind) errMultipleBaseLayers = fmt.Errorf("there can only be one base runtime layer, non-default layers must have '%s' set", wh.AnnotationLayerRuntimeCapability) errMultipleInfraLayers = errors.New("there can only be one infrastructure layer") errLayersMustBeK8sManifests = errors.New("layer must describe valid K8s manifests") ) // AnnotationError occurs when an annotation value does pass its associated validation function. // e.g. when a required annotation is missing, or it does not have the expected format. type AnnotationError struct { Err error Annotation string Values []string } func (err AnnotationError) Error() string { if len(err.Values) == 0 { return fmt.Sprintf("annotation '%s' is invalid: %v", err.Annotation, err.Err) } values := strings.Join(err.Values, ",") return fmt.Sprintf("'%s' is invalid for annotation '%s': %v", values, err.Annotation, err.Err) } func NewAnnotationError(err error, annotation string, values ...string) AnnotationError { return AnnotationError{ Err: err, Annotation: annotation, Values: values, } } // ImageLayersError occurs when one or more layers in a v1.Image are not valid. // e.g. when there are one or more base or infrastructure layers defined. type ImageLayersError struct { Err error Count int } func (err ImageLayersError) Error() string { return fmt.Sprintf("%d layers are invalid: %v", err.Count, err.Err) } func NewImageLayersError(err error, count int) ImageLayersError { return ImageLayersError{ Err: err, Count: count, } } // DescriptorError occurs when a descriptor defines values in an annotation that are not present on the root node. // e.g. an provider image has "gke" provider, but the parent index only has "sds,generic". type DescriptorError struct { Annotation string Value string RootValues []string } func (err DescriptorError) Error() string { if len(err.RootValues) == 0 || err.RootValues[0] == "" { return fmt.Sprintf("descriptor has '%s' but root does not", err.Annotation) } return fmt.Sprintf("descriptor has '%s'='%s' which is not in root set '%s'", err.Annotation, err.Value, err.RootValues) } func NewDescriptorError(annotation, value string, rootValues []string) DescriptorError { return DescriptorError{ Annotation: annotation, Value: value, RootValues: rootValues, } }