func/pkg/functions/function_options.go

140 lines
4.9 KiB
Go

package functions
import (
"fmt"
"k8s.io/apimachinery/pkg/api/resource"
)
type Options struct {
Scale *ScaleOptions `yaml:"scale,omitempty"`
Resources *ResourcesOptions `yaml:"resources,omitempty"`
}
type ScaleOptions struct {
Min *int64 `yaml:"min,omitempty" jsonschema_extras:"minimum=0"`
Max *int64 `yaml:"max,omitempty" jsonschema_extras:"minimum=0"`
Metric *string `yaml:"metric,omitempty" jsonschema:"enum=concurrency,enum=rps"`
Target *float64 `yaml:"target,omitempty" jsonschema_extras:"minimum=0.01"`
Utilization *float64 `yaml:"utilization,omitempty" jsonschema:"minimum=1,maximum=100"`
}
type ResourcesOptions struct {
Requests *ResourcesRequestsOptions `yaml:"requests,omitempty"`
Limits *ResourcesLimitsOptions `yaml:"limits,omitempty"`
}
type ResourcesLimitsOptions struct {
CPU *string `yaml:"cpu,omitempty" jsonschema:"pattern=^([+-]?[0-9.]+)([eEinumkKMGTP]*[-+]?[0-9]*)$"`
Memory *string `yaml:"memory,omitempty" jsonschema:"pattern=^([+-]?[0-9.]+)([eEinumkKMGTP]*[-+]?[0-9]*)$"`
Concurrency *int64 `yaml:"concurrency,omitempty" jsonschema_extras:"minimum=0"`
}
type ResourcesRequestsOptions struct {
CPU *string `yaml:"cpu,omitempty" jsonschema:"pattern=^([+-]?[0-9.]+)([eEinumkKMGTP]*[-+]?[0-9]*)$"`
Memory *string `yaml:"memory,omitempty" jsonschema:"pattern=^([+-]?[0-9.]+)([eEinumkKMGTP]*[-+]?[0-9]*)$"`
}
// validateOptions checks that input Options are correctly set.
// Returns array of error messages, empty if no errors are found
func validateOptions(options Options) (errors []string) {
// options.scale
if options.Scale != nil {
if options.Scale.Min != nil {
if *options.Scale.Min < 0 {
errors = append(errors, fmt.Sprintf("options field \"scale.min\" has invalid value set: %d, the value must be greater than \"0\"",
*options.Scale.Min))
}
}
if options.Scale.Max != nil {
if *options.Scale.Max < 0 {
errors = append(errors, fmt.Sprintf("options field \"scale.max\" has invalid value set: %d, the value must be greater than \"0\"",
*options.Scale.Max))
}
}
if options.Scale.Min != nil && options.Scale.Max != nil {
if *options.Scale.Max < *options.Scale.Min {
errors = append(errors, "options field \"scale.max\" value must be greater or equal to \"scale.min\"")
}
}
if options.Scale.Metric != nil {
if *options.Scale.Metric != "concurrency" && *options.Scale.Metric != "rps" {
errors = append(errors, fmt.Sprintf("options field \"scale.metric\" has invalid value set: %s, allowed is only \"concurrency\" or \"rps\"",
*options.Scale.Metric))
}
}
if options.Scale.Target != nil {
if *options.Scale.Target < 0.01 {
errors = append(errors, fmt.Sprintf("options field \"scale.target\" has value set to \"%f\", but it must not be less than 0.01",
*options.Scale.Target))
}
}
if options.Scale.Utilization != nil {
if *options.Scale.Utilization < 1 || *options.Scale.Utilization > 100 {
errors = append(errors,
fmt.Sprintf("options field \"scale.utilization\" has value set to \"%f\", but it must not be less than 1 or greater than 100",
*options.Scale.Utilization))
}
}
}
// options.resource
if options.Resources != nil {
// options.resource.requests
if options.Resources.Requests != nil {
if options.Resources.Requests.CPU != nil {
_, err := resource.ParseQuantity(*options.Resources.Requests.CPU)
if err != nil {
errors = append(errors, fmt.Sprintf("options field \"resources.requests.cpu\" has invalid value set: \"%s\"; \"%s\"",
*options.Resources.Requests.CPU, err.Error()))
}
}
if options.Resources.Requests.Memory != nil {
_, err := resource.ParseQuantity(*options.Resources.Requests.Memory)
if err != nil {
errors = append(errors, fmt.Sprintf("options field \"resources.requests.memory\" has invalid value set: \"%s\"; \"%s\"",
*options.Resources.Requests.Memory, err.Error()))
}
}
}
// options.resource.limits
if options.Resources.Limits != nil {
if options.Resources.Limits.CPU != nil {
_, err := resource.ParseQuantity(*options.Resources.Limits.CPU)
if err != nil {
errors = append(errors, fmt.Sprintf("options field \"resources.limits.cpu\" has invalid value set: \"%s\"; \"%s\"",
*options.Resources.Limits.CPU, err.Error()))
}
}
if options.Resources.Limits.Memory != nil {
_, err := resource.ParseQuantity(*options.Resources.Limits.Memory)
if err != nil {
errors = append(errors, fmt.Sprintf("options field \"resources.limits.memory\" has invalid value set: \"%s\"; \"%s\"",
*options.Resources.Limits.Memory, err.Error()))
}
}
if options.Resources.Limits.Concurrency != nil {
if *options.Resources.Limits.Concurrency < 0 {
errors = append(errors, fmt.Sprintf("options field \"resources.limits.concurrency\" has value set to \"%d\", but it must not be less than 0",
*options.Resources.Limits.Concurrency))
}
}
}
}
return
}