From 10fc310a43311e6a457ae91b990d7dacfe745c5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Weisbarth?= Date: Fri, 19 Sep 2025 17:17:23 +0200 Subject: [PATCH 01/20] Revert "Temporarily remove the package binding_request to do that in a separate PR;" This reverts commit 36934ab5434fabc2e5a07fe73f3fb8719e357dc0. --- .../binding_request/autoscaler-policy.json | 1 + .../binding-configuration.json | 1 + .../binding_request/binding-request-parser.go | 32 + .../binding-request-parser_suite_test.go | 13 + .../binding-request-parser_test.go | 172 ++++ .../api/binding_request/binding-request.json | 1 + .../clean_parser/json-structure.go | 70 ++ .../binding_request/clean_parser/parser.go | 128 +++ .../binding_request/combined_parser/parser.go | 35 + .../legacy-binding-request.json | 911 ++++++++++++++++++ .../legacy_parser/json-structure.go | 67 ++ .../binding_request/legacy_parser/parser.go | 111 +++ .../binding_request/shared_definitions.json | 1 + 13 files changed, 1543 insertions(+) create mode 120000 src/autoscaler/api/binding_request/autoscaler-policy.json create mode 120000 src/autoscaler/api/binding_request/binding-configuration.json create mode 100644 src/autoscaler/api/binding_request/binding-request-parser.go create mode 100644 src/autoscaler/api/binding_request/binding-request-parser_suite_test.go create mode 100644 src/autoscaler/api/binding_request/binding-request-parser_test.go create mode 120000 src/autoscaler/api/binding_request/binding-request.json create mode 100644 src/autoscaler/api/binding_request/clean_parser/json-structure.go create mode 100644 src/autoscaler/api/binding_request/clean_parser/parser.go create mode 100644 src/autoscaler/api/binding_request/combined_parser/parser.go create mode 100644 src/autoscaler/api/binding_request/legacy-binding-request.json create mode 100644 src/autoscaler/api/binding_request/legacy_parser/json-structure.go create mode 100644 src/autoscaler/api/binding_request/legacy_parser/parser.go create mode 120000 src/autoscaler/api/binding_request/shared_definitions.json diff --git a/src/autoscaler/api/binding_request/autoscaler-policy.json b/src/autoscaler/api/binding_request/autoscaler-policy.json new file mode 120000 index 0000000000..c684b4a64e --- /dev/null +++ b/src/autoscaler/api/binding_request/autoscaler-policy.json @@ -0,0 +1 @@ +../../../../schema/json/autoscaler-policy.json \ No newline at end of file diff --git a/src/autoscaler/api/binding_request/binding-configuration.json b/src/autoscaler/api/binding_request/binding-configuration.json new file mode 120000 index 0000000000..7a02de2ce5 --- /dev/null +++ b/src/autoscaler/api/binding_request/binding-configuration.json @@ -0,0 +1 @@ +../../../../schema/json/binding-configuration.json \ No newline at end of file diff --git a/src/autoscaler/api/binding_request/binding-request-parser.go b/src/autoscaler/api/binding_request/binding-request-parser.go new file mode 100644 index 0000000000..b14b578f66 --- /dev/null +++ b/src/autoscaler/api/binding_request/binding-request-parser.go @@ -0,0 +1,32 @@ +package binding_request + +import ( + "fmt" + + "github.com/xeipuuv/gojsonschema" + + "code.cloudfoundry.org/app-autoscaler/src/autoscaler/models" +) + +type Parameters struct { + // 🚧 To-do: We should distinguish between raw data and correctly validated data. + Configuration *models.BindingConfig + + // 🚧 To-do: We should distinguish between raw data and correctly validated data. + ScalingPolicy *models.ScalingPolicy +} + +type JsonSchemaError []gojsonschema.ResultError + +func (e JsonSchemaError) Error() string { + var errors []gojsonschema.ResultError = e + return fmt.Sprintf("%s", errors) +} + +type Parser interface { + // Default policies are specified on service-instance-level. Consequently, we need to leave the + // field Parameters.ScalingPolicy empty when no policy has been specified and instead … let the + // consumer of the BindingRequest decided what to do with this (i.e. he will use then the + // default-policy.) + Parse(bindingReqParams string) (Parameters, error) +} diff --git a/src/autoscaler/api/binding_request/binding-request-parser_suite_test.go b/src/autoscaler/api/binding_request/binding-request-parser_suite_test.go new file mode 100644 index 0000000000..8a9ee60158 --- /dev/null +++ b/src/autoscaler/api/binding_request/binding-request-parser_suite_test.go @@ -0,0 +1,13 @@ +package binding_request_test + +import ( + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + "testing" +) + +func TestServer(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "BindingRequestParser test suite") +} diff --git a/src/autoscaler/api/binding_request/binding-request-parser_test.go b/src/autoscaler/api/binding_request/binding-request-parser_test.go new file mode 100644 index 0000000000..f2f35cfb1d --- /dev/null +++ b/src/autoscaler/api/binding_request/binding-request-parser_test.go @@ -0,0 +1,172 @@ +package binding_request_test + +import ( + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + br "code.cloudfoundry.org/app-autoscaler/src/autoscaler/api/binding_request" + clp "code.cloudfoundry.org/app-autoscaler/src/autoscaler/api/binding_request/clean_parser" + cp "code.cloudfoundry.org/app-autoscaler/src/autoscaler/api/binding_request/combined_parser" + lp "code.cloudfoundry.org/app-autoscaler/src/autoscaler/api/binding_request/legacy_parser" + "code.cloudfoundry.org/app-autoscaler/src/autoscaler/models" +) + +var _ = Describe("BindingRequestParsers", func() { + const cleanSchemaFilePath string = "file://./binding-request.json" + const validModernBindingRequestRaw string = ` + { + "configuration": { + "app_guid": "8d0cee08-23ad-4813-a779-ad8118ea0b91", + "custom_metrics": { + "metric_submission_strategy": { + "allow_from": "bound_app" + } + } + }, + "scaling-policy": { + "instance_min_count": 1, + "instance_max_count": 4, + "scaling_rules": [ + { + "metric_type": "memoryutil", + "breach_duration_secs": 600, + "threshold": 30, + "operator": "<", + "cool_down_secs": 300, + "adjustment": "-1" + }, + { + "metric_type": "memoryutil", + "breach_duration_secs": 600, + "threshold": 90, + "operator": ">=", + "cool_down_secs": 300, + "adjustment": "+1" + } + ] + } + }` + const validLegacyBindingRequestRaw string = ` + { + "configuration": { + "app_guid": "8d0cee08-23ad-4813-a779-ad8118ea0b91", + "custom_metrics": { + "metric_submission_strategy": { + "allow_from": "bound_app" + } + } + }, + "instance_min_count": 1, + "instance_max_count": 4, + "scaling_rules": [ + { + "metric_type": "memoryutil", + "breach_duration_secs": 600, + "threshold": 30, + "operator": "<", + "cool_down_secs": 300, + "adjustment": "-1" + }, + { + "metric_type": "memoryutil", + "breach_duration_secs": 600, + "threshold": 90, + "operator": ">=", + "cool_down_secs": 300, + "adjustment": "+1" + } + ] + }` + + Describe("CleanBindingRequestParser", func() { + var ( + cleanParser clp.CleanBindingRequestParser + err error + ) + var _ = BeforeEach(func() { + cleanParser, err = clp.NewFromFile(cleanSchemaFilePath) + Expect(err).NotTo(HaveOccurred()) + }) + Context("When using the new format for binding-requests", func() { + Context("and parsing a valid and complete one", func() { + It("should return a correctly populated BindingRequestParameters", func() { + bindingRequestRaw := validModernBindingRequestRaw + + bindingRequest, err := cleanParser.Parse(bindingRequestRaw) + + Expect(err).NotTo(HaveOccurred()) + Expect(bindingRequest.Configuration.AppGUID).To( + Equal(models.GUID("8d0cee08-23ad-4813-a779-ad8118ea0b91"))) + }) + }) + }) + }) + + Describe("LegacyBindingRequestParser", func() { + var ( + legacyParser lp.LegacyBindingRequestParser + err error + ) + var _ = BeforeEach(func() { + legacyParser, err = lp.New() + Expect(err).NotTo(HaveOccurred()) + }) + + Context("When using the legacy format for binding-requests", func() { + It("should return a correctly populated BindingRequestParameters", func() { + bindingRequestRaw := validLegacyBindingRequestRaw + + bindingRequest, err := legacyParser.Parse(bindingRequestRaw) + + Expect(err).NotTo(HaveOccurred()) + Expect(bindingRequest.Configuration.AppGUID). + To(Equal(models.GUID("8d0cee08-23ad-4813-a779-ad8118ea0b91"))) + // 🚧 To-do: Add a few more field-comparisons; + }) + }) + }) + + Describe("CombinedBindingRequestParser", func() { + var ( + cleanParser clp.CleanBindingRequestParser + legacyParser lp.LegacyBindingRequestParser + combinedParser cp.CombinedBindingRequestParser + + err error + ) + var _ = BeforeEach(func() { + cleanParser, err = clp.NewFromFile(cleanSchemaFilePath) + Expect(err).NotTo(HaveOccurred()) + legacyParser, err = lp.New() + Expect(err).NotTo(HaveOccurred()) + combinedParser = cp.New([]br.Parser{cleanParser, legacyParser}) + }) + + Context("When using the new format for binding-requests", func() { + Context("and parsing a valid and complete one", func() { + It("should return a correctly populated BindingRequestParameters", func() { + bindingRequestRaw := validModernBindingRequestRaw + + bindingRequest, err := combinedParser.Parse(bindingRequestRaw) + + Expect(err).NotTo(HaveOccurred()) + Expect(bindingRequest.Configuration.AppGUID).To( + Equal(models.GUID("8d0cee08-23ad-4813-a779-ad8118ea0b91"))) + }) + }) + }) + + Context("When using the legacy format for binding-requests", func() { + It("should return a correctly populated BindingRequestParameters", func() { + bindingRequestRaw := validLegacyBindingRequestRaw + + bindingRequest, err := combinedParser.Parse(bindingRequestRaw) + + Expect(err).NotTo(HaveOccurred()) + Expect(bindingRequest.Configuration.AppGUID). + To(Equal(models.GUID("8d0cee08-23ad-4813-a779-ad8118ea0b91"))) + // 🚧 To-do: Add a few more field-comparisons; + }) + }) + }) +}) diff --git a/src/autoscaler/api/binding_request/binding-request.json b/src/autoscaler/api/binding_request/binding-request.json new file mode 120000 index 0000000000..588a0dc2f7 --- /dev/null +++ b/src/autoscaler/api/binding_request/binding-request.json @@ -0,0 +1 @@ +../../../../schema/json/binding-request.json \ No newline at end of file diff --git a/src/autoscaler/api/binding_request/clean_parser/json-structure.go b/src/autoscaler/api/binding_request/clean_parser/json-structure.go new file mode 100644 index 0000000000..519799b480 --- /dev/null +++ b/src/autoscaler/api/binding_request/clean_parser/json-structure.go @@ -0,0 +1,70 @@ +package clean_parser + +type parameters struct { + Configuration *bindingCfg `json:"configuration"` + ScalingPolicy *scalingPolicy `json:"scaling-policy"` +} + +// ================================================================================ +// Binding-configuration +// ================================================================================ + +type bindingCfg struct { + CustomMetricsCfg customMetricsCfg + AppGuid string `json:"app_guid"` +} + +type customMetricsCfg struct { + MetricSubmStrat metricSubmStrat `json:"metric_submission_strategy"` +} + +type metricSubmStrat struct { + AllowFrom string `json:"allow_from"` +} + +// ================================================================================ +// Scaling-policy +// ================================================================================ + +type scalingPolicy struct { + SchemaVersion string `json:"schema-version"` + InstanceMinCount int `json:"instance_min_count"` + InstanceMaxCount int `json:"instance_max_count"` + ScalingRules []scalingRule `json:"scaling_rules,omitempty"` + Schedules *scalingSchedule `json:"schedules,omitempty"` +} + +type scalingRule struct { + MetricType string `json:"metric_type"` + BreachDurationSecs int `json:"breach_duration_secs,omitempty"` + Threshold int64 `json:"threshold"` + Operator string `json:"operator"` + CoolDownSecs int `json:"cool_down_secs,omitempty"` + Adjustment string `json:"adjustment"` +} + +type scalingSchedule struct { + Timezone string `json:"timezone"` + RecurringSchedule []recurringSchedule `json:"recurring_schedule,omitempty"` + SpecificDate []specificDate `json:"specific_date,omitempty"` +} + +type recurringSchedule struct { + StartTime string `json:"start_time"` + EndTime string `json:"end_time"` + DaysOfWeek []int `json:"days_of_week,omitempty"` + DaysOfMonth []int `json:"days_of_month,omitempty"` + InstanceMinCount int `json:"instance_min_count"` + InstanceMaxCount int `json:"instance_max_count"` + InitialMinInstanceCount int `json:"initial_min_instance_count,omitempty"` + StartDate string `json:"start_date,omitempty"` + EndDate string `json:"end_date,omitempty"` +} + +type specificDate struct { + StartDateTime string `json:"start_date_time"` + EndDateTime string `json:"end_date_time"` + InstanceMinCount int `json:"instance_min_count"` + InstanceMaxCount int `json:"instance_max_count"` + InitialMinInstanceCount int `json:"initial_min_instance_count,omitempty"` +} diff --git a/src/autoscaler/api/binding_request/clean_parser/parser.go b/src/autoscaler/api/binding_request/clean_parser/parser.go new file mode 100644 index 0000000000..5a5c711105 --- /dev/null +++ b/src/autoscaler/api/binding_request/clean_parser/parser.go @@ -0,0 +1,128 @@ +package clean_parser + +import ( + "encoding/json" + + "github.com/xeipuuv/gojsonschema" + + "code.cloudfoundry.org/app-autoscaler/src/autoscaler/api/binding_request" + "code.cloudfoundry.org/app-autoscaler/src/autoscaler/models" +) + +type CleanBindingRequestParser struct { + schema *gojsonschema.Schema +} + +var _ binding_request.Parser = CleanBindingRequestParser{} + +func new(jsonLoader gojsonschema.JSONLoader) (CleanBindingRequestParser, error) { + schema, err := gojsonschema.NewSchema(jsonLoader) + if err != nil { + return CleanBindingRequestParser{}, err + } else { + return CleanBindingRequestParser{schema: schema}, nil + } +} + +func NewFromString(jsonSchema string) (CleanBindingRequestParser, error) { + schemaLoader := gojsonschema.NewStringLoader(jsonSchema) + return new(schemaLoader) +} + +func NewFromFile(pathToSchemaFile string) (CleanBindingRequestParser, error) { + // The type for parameter `pathToSchemaFile` is same type as used in golang's std-library + schemaLoader := gojsonschema.NewReferenceLoader(pathToSchemaFile) + return new(schemaLoader) +} + +func (p CleanBindingRequestParser) Parse(bindingReqParams string) (binding_request.Parameters, error) { + documentLoader := gojsonschema.NewStringLoader(bindingReqParams) + validationResult, err := p.schema.Validate(documentLoader) + if err != nil { + // Defined by the implementation of `Validate`, this only happens, if the provided document + // (in this context `documentLoader`) can not be loaded. + return binding_request.Parameters{}, err + } else if !validationResult.Valid() { + // The error contains a description of all detected violations against the schema. + allErrors := binding_request.JsonSchemaError(validationResult.Errors()) + return binding_request.Parameters{}, allErrors + } + + var parsedParameters parameters + err = json.Unmarshal([]byte(bindingReqParams), &parsedParameters) + if err != nil { + return binding_request.Parameters{}, err + } + + return toBindingParameters(parsedParameters), nil +} + +func toBindingParameters(params parameters) binding_request.Parameters { + result := binding_request.Parameters{} + if params.Configuration != nil { + result.Configuration = &models.BindingConfig{} + + result.Configuration.AppGUID = models.GUID(params.Configuration.AppGuid) + result.Configuration.SetCustomMetricsStrategy(params.Configuration.CustomMetricsCfg.MetricSubmStrat.AllowFrom) + } + + if params.ScalingPolicy != nil { + result.ScalingPolicy = &models.ScalingPolicy{} + + result.ScalingPolicy.InstanceMax = params.ScalingPolicy.InstanceMaxCount + result.ScalingPolicy.InstanceMin = params.ScalingPolicy.InstanceMinCount + + result.ScalingPolicy.ScalingRules = []*models.ScalingRule{} + for _, rule := range params.ScalingPolicy.ScalingRules { + r := models.ScalingRule{ + MetricType: rule.MetricType, + BreachDurationSeconds: rule.BreachDurationSecs, + Threshold: rule.Threshold, + Operator: rule.Operator, + CoolDownSeconds: rule.CoolDownSecs, + Adjustment: rule.Adjustment, + } + result.ScalingPolicy.ScalingRules = append(result.ScalingPolicy.ScalingRules, &r) + } + + if params.ScalingPolicy.Schedules != nil { + result.ScalingPolicy.Schedules = &models.ScalingSchedules{ + Timezone: params.ScalingPolicy.Schedules.Timezone, + } + + if params.ScalingPolicy.Schedules.RecurringSchedule != nil { + result.ScalingPolicy.Schedules.RecurringSchedules = []*models.RecurringSchedule{} + for _, schedule := range params.ScalingPolicy.Schedules.RecurringSchedule { + rs := models.RecurringSchedule{ + StartTime: schedule.StartTime, + EndTime: schedule.EndTime, + DaysOfWeek: schedule.DaysOfWeek, + DaysOfMonth: schedule.DaysOfMonth, + ScheduledInstanceMin: schedule.InstanceMinCount, + ScheduledInstanceMax: schedule.InstanceMaxCount, + ScheduledInstanceInit: schedule.InitialMinInstanceCount, + StartDate: schedule.StartDate, + EndDate: schedule.EndDate, + } + result.ScalingPolicy.Schedules.RecurringSchedules = append(result.ScalingPolicy.Schedules.RecurringSchedules, &rs) + } + } + + if params.ScalingPolicy.Schedules.SpecificDate != nil { + result.ScalingPolicy.Schedules.SpecificDateSchedules = []*models.SpecificDateSchedule{} + for _, specificDate := range params.ScalingPolicy.Schedules.SpecificDate { + sd := models.SpecificDateSchedule{ + StartDateTime: specificDate.StartDateTime, + EndDateTime: specificDate.EndDateTime, + ScheduledInstanceMin: specificDate.InstanceMinCount, + ScheduledInstanceMax: specificDate.InstanceMaxCount, + ScheduledInstanceInit: specificDate.InitialMinInstanceCount, + } + result.ScalingPolicy.Schedules.SpecificDateSchedules = append(result.ScalingPolicy.Schedules.SpecificDateSchedules, &sd) + } + } + } + } + + return result +} diff --git a/src/autoscaler/api/binding_request/combined_parser/parser.go b/src/autoscaler/api/binding_request/combined_parser/parser.go new file mode 100644 index 0000000000..96e23082c0 --- /dev/null +++ b/src/autoscaler/api/binding_request/combined_parser/parser.go @@ -0,0 +1,35 @@ +package combined_parser + +import ( + "code.cloudfoundry.org/app-autoscaler/src/autoscaler/api/binding_request" +) + +// Combined parser that tries out all other parser that are associated to it in order +// and returns the first successful result. +// +// In case all associated parser fail, it returns the error of the first one. +type CombinedBindingRequestParser struct { + parsers []binding_request.Parser +} + +// Ensure CombinedBindingRequestParser implements the binding_request.Parser interface. +var _ binding_request.Parser = CombinedBindingRequestParser{} + +func New(parsers []binding_request.Parser) CombinedBindingRequestParser { + return CombinedBindingRequestParser{parsers: parsers} +} + +func (p CombinedBindingRequestParser) Parse( + bindingReqParams string, +) (binding_request.Parameters, error) { + var firstErr error + for i, parser := range p.parsers { + params, err := parser.Parse(bindingReqParams) + if i == 0 && err != nil { + firstErr = err // Store the first error to return later if no parser is successful. + } else if err == nil { + return params, nil + } + } + return binding_request.Parameters{}, firstErr +} diff --git a/src/autoscaler/api/binding_request/legacy-binding-request.json b/src/autoscaler/api/binding_request/legacy-binding-request.json new file mode 100644 index 0000000000..d3c889875d --- /dev/null +++ b/src/autoscaler/api/binding_request/legacy-binding-request.json @@ -0,0 +1,911 @@ +{ + "$schema": "http://json-schema.org/draft-05/schema#", + "title": "", + "description": "Legacy schema for the combination of a scaling-policy and the configuration of service-bindings with instances of Application Autoscaler.", + "type": "object", + + "properties": { + "configuration": { + "$ref": "./binding-configuration.json" + }, + "instance_min_count": { + "$id": "#/properties/instance_min_count", + "type": "integer", + "minimum": 1, + "title": "Minimum number of application instance always runs" + }, + "instance_max_count": { + "$id": "#/properties/instance_max_count", + "type": "integer", + "title": "Maximum how many instances of application can be provisioned as part o f application scaling" + }, + "scaling_rules": { + "$id": "#/properties/scaling_rules", + "type": "array", + "title": "Dynamic Scaling_rules Schema", + "items": { + "$id": "#/properties/scaling_rules/items", + "type": "object", + "title": "Scaling_rules Items Schema", + "required": [ + "metric_type", + "threshold", + "operator", + "adjustment" + ], + "properties": { + "metric_type": { + "$id": "#/properties/scaling_rules/items/properties/metric_type", + "type": "string", + "title": "The Metric_type Schema", + "pattern": "^[a-zA-Z0-9_]+$", + "maxLength": 100 + }, + "breach_duration_secs": { + "$id": "#/properties/scaling_rules/items/properties/breach_duration_secs", + "type": "integer", + "title": "The Breach_duration_secs Schema", + "description": "The length of the past period when a scaling action might be triggered based on metric usage", + "maximum": 3600, + "minimum": 60 + }, + "threshold": { + "$id": "#/properties/scaling_rules/items/properties/threshold", + "type": "integer", + "title": "The Threshold Schema" + }, + "operator": { + "$id": "#/properties/scaling_rules/items/properties/operator", + "type": "string", + "title": "The Operator Schema", + "description": "Operator is used in combination with the threshold value to compare the current metric value", + "enum": [ + "<", + ">", + "<=", + ">=" + ] + }, + "cool_down_secs": { + "$id": "#/properties/scaling_rules/items/properties/cool_down_secs", + "type": "integer", + "title": "The Cool_down_secs Schema", + "description": "The interval between two successive scaling activity", + "maximum": 3600, + "minimum": 60 + }, + "adjustment": { + "$id": "#/properties/scaling_rules/items/properties/adjustment", + "type": "string", + "title": "The Adjustment Schema", + "description": "Magnitude of scaling in each step, +1 means scale up 1 Instance -2 means scale down 2 instances", + "pattern": "^[-+][1-9]+[0-9]*%?$" + } + } + } + }, + "schedules": { + "$id": "#/properties/schedules", + "type": "object", + "title": "The Scaling Schedules Schema", + "required": [ + "timezone" + ], + "anyOf": [ + { + "required": [ + "recurring_schedule" + ] + }, + { + "required": [ + "specific_date" + ] + } + ], + "properties": { + "timezone": { + "$id": "#/properties/schedules/properties/timezone", + "type": "string", + "title": "The Timezone Schema", + "pattern": "^(.*)$", + "enum": [ + "Etc/GMT+12", + "Etc/GMT+11", + "Pacific/Midway", + "Pacific/Niue", + "Pacific/Pago_Pago", + "Pacific/Samoa", + "US/Samoa", + "Etc/GMT+10", + "HST", + "Pacific/Honolulu", + "Pacific/Johnston", + "Pacific/Rarotonga", + "Pacific/Tahiti", + "US/Hawaii", + "Pacific/Marquesas", + "America/Adak", + "America/Atka", + "Etc/GMT+9", + "Pacific/Gambier", + "US/Aleutian", + "America/Anchorage", + "America/Juneau", + "America/Metlakatla", + "America/Nome", + "America/Sitka", + "America/Yakutat", + "Etc/GMT+8", + "Pacific/Pitcairn", + "US/Alaska", + "America/Creston", + "America/Dawson", + "America/Dawson_Creek", + "America/Ensenada", + "America/Hermosillo", + "America/Los_Angeles", + "America/Phoenix", + "America/Santa_Isabel", + "America/Tijuana", + "America/Vancouver", + "America/Whitehorse", + "Canada/Pacific", + "Canada/Yukon", + "Etc/GMT+7", + "MST", + "Mexico/BajaNorte", + "PST8PDT", + "US/Arizona", + "US/Pacific", + "US/Pacific-New", + "America/Belize", + "America/Boise", + "America/Cambridge_Bay", + "America/Chihuahua", + "America/Costa_Rica", + "America/Denver", + "America/Edmonton", + "America/El_Salvador", + "America/Guatemala", + "America/Inuvik", + "America/Managua", + "America/Mazatlan", + "America/Ojinaga", + "America/Regina", + "America/Shiprock", + "America/Swift_Current", + "America/Tegucigalpa", + "America/Yellowknife", + "Canada/East-Saskatchewan", + "Canada/Mountain", + "Canada/Saskatchewan", + "Etc/GMT+6", + "MST7MDT", + "Mexico/BajaSur", + "Navajo", + "Pacific/Galapagos", + "US/Mountain", + "America/Atikokan", + "America/Bahia_Banderas", + "America/Bogota", + "America/Cancun", + "America/Cayman", + "America/Chicago", + "America/Coral_Harbour", + "America/Eirunepe", + "America/Guayaquil", + "America/Indiana/Knox", + "America/Indiana/Tell_City", + "America/Jamaica", + "America/Knox_IN", + "America/Lima", + "America/Matamoros", + "America/Menominee", + "America/Merida", + "America/Mexico_City", + "America/Monterrey", + "America/North_Dakota/Beulah", + "America/North_Dakota/Center", + "America/North_Dakota/New_Salem", + "America/Panama", + "America/Porto_Acre", + "America/Rainy_River", + "America/Rankin_Inlet", + "America/Resolute", + "America/Rio_Branco", + "America/Winnipeg", + "Brazil/Acre", + "CST6CDT", + "Canada/Central", + "Chile/EasterIsland", + "EST", + "Etc/GMT+5", + "Jamaica", + "Mexico/General", + "Pacific/Easter", + "US/Central", + "US/Indiana-Starke", + "America/Caracas", + "America/Anguilla", + "America/Antigua", + "America/Aruba", + "America/Asuncion", + "America/Barbados", + "America/Blanc-Sablon", + "America/Boa_Vista", + "America/Campo_Grande", + "America/Cuiaba", + "America/Curacao", + "America/Detroit", + "America/Dominica", + "America/Fort_Wayne", + "America/Grand_Turk", + "America/Grenada", + "America/Guadeloupe", + "America/Guyana", + "America/Havana", + "America/Indiana/Indianapolis", + "America/Indiana/Marengo", + "America/Indiana/Petersburg", + "America/Indiana/Vevay", + "America/Indiana/Vincennes", + "America/Indiana/Winamac", + "America/Indianapolis", + "America/Iqaluit ", + "America/Kentucky/Louisville ", + "America/Kentucky/Monticello", + "America/Kralendijk", + "America/La_Paz", + "America/Louisville ", + "America/Lower_Princes", + "America/Manaus", + "America/Marigot", + "America/Martinique", + "America/Montreal", + "America/Montserrat", + "America/Nassau", + "America/New_York", + "America/Nipigon", + "America/Pangnirtung ", + "America/Port-au-Prince ", + "America/Port_of_Spain", + "America/Porto_Velho", + "America/Puerto_Rico ", + "America/Santo_Domingo ", + "America/St_Barthelemy", + "America/St_Kitts", + "America/St_Lucia", + "America/St_Thomas", + "America/St_Vincent", + "America/Thunder_Bay", + "America/Toronto", + "America/Tortola", + "America/Virgin", + "Brazil/West", + "Canada/Eastern", + "Cuba", + "EST5EDT", + "Etc/GMT+4", + "US/East-Indiana", + "US/Eastern", + "US/Michigan", + "America/Araguaina ", + "America/Argentina/Buenos_Aires ", + "America/Argentina/Catamarca ", + "America/Argentina/ComodRivadavia ", + "America/Argentina/Cordoba ", + "America/Argentina/Jujuy ", + "America/Argentina/La_Rioja ", + "America/Argentina/Mendoza ", + "America/Argentina/Rio_Gallegos ", + "America/Argentina/Salta ", + "America/Argentina/San_Juan ", + "America/Argentina/San_Luis ", + "America/Argentina/Tucuman ", + "America/Argentina/Ushuaia", + "America/Bahia", + "America/Belem", + "America/Buenos_Aires", + "America/Catamarca", + "America/Cayenne", + "America/Cordoba", + "America/Fortaleza", + "America/Glace_Bay", + "America/Goose_Bay", + "America/Halifax", + "America/Jujuy", + "America/Maceio", + "America/Mendoza", + "America/Moncton", + "America/Montevideo", + "America/Paramaribo", + "America/Recife", + "America/Rosario", + "America/Santarem", + "America/Santiago", + "America/Sao_Paulo", + "America/Thule", + "Antarctica/Palmer", + "Antarctica/Rothera", + "Atlantic/Bermuda", + "Atlantic/Stanley", + "Brazil/East", + "Canada/Atlantic", + "Chile/Continental", + "Etc/GMT+3", + "America/St_Johns", + "Canada/Newfoundland", + "America/Godthab", + "America/Miquelon", + "America/Noronha ", + "Atlantic/South_Georgia", + "Brazil/DeNoronha", + "Etc/GMT+2", + "Atlantic/Cape_Verde", + "Etc/GMT+1", + "Africa/Abidjan", + "Africa/Accra", + "Africa/Bamako", + "Africa/Banjul", + "Africa/Bissau", + "Africa/Conakry", + "Africa/Dakar", + "Africa/Freetown", + "Africa/Lome", + "Africa/Monrovia", + "Africa/Nouakchott", + "Africa/Ouagadougou", + "Africa/Sao_Tome", + "Africa/Timbuktu", + "America/Danmarkshavn", + "America/Scoresbysund", + "Atlantic/Azores", + "Atlantic/Reykjavik", + "Atlantic/St_Helena", + "Etc/GMT", + "Etc/GMT+0", + "Etc/GMT-0", + "Etc/GMT0", + "Etc/Greenwich", + "Etc/UCT", + "Etc/UTC", + "Etc/Universal", + "Etc/Zulu", + "GMT", + "GMT+0", + "GMT-0", + "GMT0", + "Greenwich", + "Iceland", + "UCT", + "UTC", + "Universal", + "Zulu", + "Africa/Algiers", + "Africa/Bangui", + "Africa/Brazzaville", + "Africa/Casablanca", + "Africa/Douala", + "Africa/El_Aaiun", + "Africa/Kinshasa", + "Africa/Lagos", + "Africa/Libreville", + "Africa/Luanda", + "Africa/Malabo", + "Africa/Ndjamena", + "Africa/Niamey", + "Africa/Porto-Novo", + "Africa/Tunis", + "Africa/Windhoek", + "Atlantic/Canary", + "Atlantic/Faeroe", + "Atlantic/Faroe", + "Atlantic/Madeira", + "Eire", + "Etc/GMT-1", + "Europe/Belfast", + "Europe/Dublin", + "Europe/Guernsey", + "Europe/Isle_of_Man", + "Europe/Jersey", + "Europe/Lisbon", + "Europe/London", + "GB", + "GB-Eire", + "Portugal", + "WET", + "Africa/Blantyre", + "Africa/Bujumbura", + "Africa/Cairo", + "Africa/Ceuta", + "Africa/Gaborone", + "Africa/Harare", + "Africa/Johannesburg", + "Africa/Kigali", + "Africa/Lubumbashi", + "Africa/Lusaka", + "Africa/Maputo", + "Africa/Maseru", + "Africa/Mbabane", + "Africa/Tripoli", + "Antarctica/Troll", + "Arctic/Longyearbyen", + "Atlantic/Jan_Mayen", + "CET", + "Egypt", + "Etc/GMT-2", + "Europe/Amsterdam", + "Europe/Andorra", + "Europe/Belgrade", + "Europe/Berlin", + "Europe/Bratislava", + "Europe/Brussels", + "Europe/Budapest", + "Europe/Busingen", + "Europe/Copenhagen", + "Europe/Gibraltar", + "Europe/Kaliningrad", + "Europe/Ljubljana", + "Europe/Luxembourg", + "Europe/Madrid", + "Europe/Malta", + "Europe/Monaco", + "Europe/Oslo", + "Europe/Paris", + "Europe/Podgorica", + "Europe/Prague", + "Europe/Rome", + "Europe/San_Marino", + "Europe/Sarajevo", + "Europe/Skopje", + "Europe/Stockholm", + "Europe/Tirane", + "Europe/Vaduz", + "Europe/Vatican", + "Europe/Vienna", + "Europe/Warsaw", + "Europe/Zagreb", + "Europe/Zurich", + "Libya", + "MET", + "Poland", + "Africa/Addis_Ababa", + "Africa/Asmara", + "Africa/Asmera", + "Africa/Dar_es_Salaam", + "Africa/Djibouti", + "Africa/Juba", + "Africa/Kampala", + "Africa/Khartoum", + "Africa/Mogadishu", + "Africa/Nairobi", + "Antarctica/Syowa", + "Asia/Aden", + "Asia/Amman", + "Asia/Baghdad", + "Asia/Bahrain", + "Asia/Beirut", + "Asia/Damascus", + "Asia/Gaza", + "Asia/Hebron", + "Asia/Istanbul", + "Asia/Jerusalem", + "Asia/Kuwait", + "Asia/Nicosia", + "Asia/Qatar", + "Asia/Riyadh", + "Asia/Tel_Aviv", + "EET", + "Etc/GMT-3", + "Europe/Athens", + "Europe/Bucharest", + "Europe/Chisinau", + "Europe/Helsinki", + "Europe/Istanbul", + "Europe/Kiev", + "Europe/Mariehamn", + "Europe/Minsk", + "Europe/Moscow", + "Europe/Nicosia", + "Europe/Riga", + "Europe/Simferopol", + "Europe/Sofia", + "Europe/Tallinn", + "Europe/Tiraspol", + "Europe/Uzhgorod", + "Europe/Vilnius", + "Europe/Volgograd", + "Europe/Zaporozhye", + "Indian/Antananarivo", + "Indian/Comoro", + "Indian/Mayotte", + "Israel", + "Turkey", + "W-SU", + "Asia/Dubai", + "Asia/Muscat", + "Asia/Tbilisi", + "Asia/Yerevan", + "Etc/GMT-4", + "Europe/Samara", + "Indian/Mahe", + "Indian/Mauritius", + "Indian/Reunion", + "Asia/Kabul", + "Asia/Tehran", + "Iran", + "Antarctica/Mawson", + "Asia/Aqtau", + "Asia/Aqtobe", + "Asia/Ashgabat", + "Asia/Ashkhabad", + "Asia/Baku", + "Asia/Dushanbe", + "Asia/Karachi", + "Asia/Oral", + "Asia/Samarkand", + "Asia/Tashkent", + "Asia/Yekaterinburg", + "Etc/GMT-5", + "Indian/Kerguelen", + "Indian/Maldives", + "Asia/Calcutta", + "Asia/Colombo", + "Asia/Kolkata", + "Asia/Kathmandu", + "Asia/Katmandu", + "Antarctica/Vostok", + "Asia/Almaty", + "Asia/Bishkek", + "Asia/Dacca", + "Asia/Dhaka", + "Asia/Kashgar", + "Asia/Novosibirsk", + "Asia/Omsk", + "Asia/Qyzylorda", + "Asia/Thimbu", + "Asia/Thimphu", + "Asia/Urumqi", + "Etc/GMT-6", + "Indian/Chagos", + "Asia/Rangoon", + "Indian/Cocos", + "Antarctica/Davis", + "Asia/Bangkok", + "Asia/Ho_Chi_Minh", + "Asia/Hovd", + "Asia/Jakarta", + "Asia/Krasnoyarsk", + "Asia/Novokuznetsk", + "Asia/Phnom_Penh", + "Asia/Pontianak", + "Asia/Saigon", + "Asia/Vientiane", + "Etc/GMT-7", + "Indian/Christmas", + "Antarctica/Casey", + "Asia/Brunei", + "Asia/Chita", + "Asia/Choibalsan", + "Asia/Chongqing", + "Asia/Chungking", + "Asia/Harbin", + "Asia/Hong_Kong", + "Asia/Irkutsk", + "Asia/Kuala_Lumpur", + "Asia/Kuching", + "Asia/Macao", + "Asia/Macau", + "Asia/Makassar", + "Asia/Manila", + "Asia/Shanghai", + "Asia/Singapore", + "Asia/Taipei", + "Asia/Ujung_Pandang", + "Asia/Ulaanbaatar", + "Asia/Ulan_Bator", + "Australia/Perth", + "Australia/West", + "Etc/GMT-8", + "Hongkong", + "PRC", + "ROC", + "Singapore", + "Australia/Eucla", + "Asia/Dili", + "Asia/Jayapura", + "Asia/Khandyga", + "Asia/Pyongyang", + "Asia/Seoul", + "Asia/Tokyo", + "Asia/Yakutsk", + "Etc/GMT-9", + "Japan", + "Pacific/Palau", + "ROK", + "Australia/Adelaide ", + "Australia/Broken_Hill", + "Australia/Darwin", + "Australia/North", + "Australia/South", + "Australia/Yancowinna ", + "Antarctica/DumontDUrville", + "Asia/Magadan", + "Asia/Sakhalin", + "Asia/Ust-Nera", + "Asia/Vladivostok", + "Australia/ACT", + "Australia/Brisbane", + "Australia/Canberra", + "Australia/Currie", + "Australia/Hobart", + "Australia/Lindeman", + "Australia/Melbourne", + "Australia/NSW", + "Australia/Queensland", + "Australia/Sydney", + "Australia/Tasmania", + "Australia/Victoria", + "Etc/GMT-10", + "Pacific/Chuuk", + "Pacific/Guam", + "Pacific/Port_Moresby", + "Pacific/Saipan", + "Pacific/Truk", + "Pacific/Yap", + "Australia/LHI", + "Australia/Lord_Howe", + "Antarctica/Macquarie", + "Asia/Srednekolymsk", + "Etc/GMT-11", + "Pacific/Bougainville", + "Pacific/Efate", + "Pacific/Guadalcanal", + "Pacific/Kosrae", + "Pacific/Noumea", + "Pacific/Pohnpei", + "Pacific/Ponape", + "Pacific/Norfolk", + "Antarctica/McMurdo", + "Antarctica/South_Pole", + "Asia/Anadyr", + "Asia/Kamchatka", + "Etc/GMT-12", + "Kwajalein", + "NZ", + "Pacific/Auckland", + "Pacific/Fiji", + "Pacific/Funafuti", + "Pacific/Kwajalein", + "Pacific/Majuro", + "Pacific/Nauru", + "Pacific/Tarawa", + "Pacific/Wake", + "Pacific/Wallis", + "NZ-CHAT", + "Pacific/Chatham", + "Etc/GMT-13", + "Pacific/Apia", + "Pacific/Enderbury", + "Pacific/Fakaofo", + "Pacific/Tongatapu", + "Etc/GMT-14", + "Pacific/Kiritimati" + ] + }, + "recurring_schedule": { + "$id": "#/properties/schedules/properties/recurring_schedule", + "type": "array", + "title": "The Recurring_schedule Schema", + "items": { + "$id": "#/properties/schedules/properties/recurring_schedule/items", + "type": "object", + "title": "The Recurring_schedule Items Schema", + "required": [ + "start_time", + "end_time", + "instance_min_count", + "instance_max_count" + ], + "oneOf": [ + { + "required": [ + "days_of_week" + ] + }, + { + "required": [ + "days_of_month" + ] + } + ], + "properties": { + "start_time": { + "$id": "#/properties/schedules/properties/recurring_schedule/items/properties/start_time", + "type": "string", + "title": "The Start_time Schema", + "pattern": "^(2[0-3]|1[0-9]|0[0-9]):([0-5][0-9])$" + }, + "end_time": { + "$id": "#/properties/schedules/properties/recurring_schedule/items/properties/end_time", + "type": "string", + "title": "The End_time Schema", + "pattern": "^(2[0-3]|1[0-9]|0[0-9]):([0-5][0-9])$" + }, + "days_of_week": { + "$id": "#/properties/schedules/properties/recurring_schedule/items/properties/days_of_week", + "type": "array", + "title": "The Days_of_week Schema", + "items": { + "$id": "#/properties/schedules/properties/recurring_schedule/items/properties/days_of_week/items", + "type": "integer", + "enum": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7 + ] + } + }, + "days_of_month": { + "$id": "#/properties/schedules/properties/recurring_schedule/items/properties/days_of_month", + "type": "array", + "title": "The Days_of_month Schema", + "items": { + "$id": "#/properties/schedules/properties/recurring_schedule/items/properties/days_of_month/items", + "type": "integer", + "enum": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31 + ] + } + }, + "instance_min_count": { + "$id": "#/properties/schedules/properties/recurring_schedule/items/properties/instance_min_count", + "type": "integer", + "title": "The Instance_min_count Schema" + }, + "instance_max_count": { + "$id": "#/properties/schedules/properties/recurring_schedule/items/properties/instance_max_count", + "type": "integer", + "title": "The Instance_max_count Schema" + }, + "initial_min_instance_count": { + "$id": "#/properties/schedules/properties/recurring_schedule/items/properties/initial_min_instance_count", + "type": "integer", + "title": "The Initial_min_instance_count Schema" + }, + "start_date": { + "oneOf": [ + { + "pattern": "^2[0-9]{3}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$", + "type": "string" + }, + { + "enum": [ + "" + ], + "type": "string" + } + ], + "description": "Start date of the recurrence in YYYY-MM-DD format" + }, + "end_date": { + "oneOf": [ + { + "pattern": "^2[0-9]{3}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$", + "type": "string" + }, + { + "enum": [ + "" + ], + "type": "string" + } + ], + "description": "End date of the recurrence in YYYY-MM-DD format" + } + } + } + }, + "specific_date": { + "$id": "#/properties/schedules/properties/specific_date", + "type": "array", + "title": "The Specific_date Schema", + "items": { + "$id": "#/properties/schedules/properties/specific_date/items", + "type": "object", + "title": "The Items Schema", + "required": [ + "start_date_time", + "end_date_time", + "instance_min_count", + "instance_max_count" + ], + "properties": { + "start_date_time": { + "$id": "#/properties/schedules/properties/specific_date/items/properties/start_date_time", + "type": "string", + "title": "The Start_date_time Schema", + "pattern": "^2[0-9]{3}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])T(2[0-3]|1[0-9]|0[0-9]):([0-5][0-9])$" + }, + "end_date_time": { + "$id": "#/properties/schedules/properties/specific_date/items/properties/end_date_time", + "type": "string", + "title": "The End_date_time Schema", + "default": "", + "pattern": "^2[0-9]{3}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])T(2[0-3]|1[0-9]|0[0-9]):([0-5][0-9])$" + }, + "instance_min_count": { + "$id": "#/properties/schedules/properties/specific_date/items/properties/instance_min_count", + "type": "integer", + "title": "The Instance_min_count Schema" + }, + "instance_max_count": { + "$id": "#/properties/schedules/properties/specific_date/items/properties/instance_max_count", + "type": "integer", + "title": "The Instance_max_count Schema" + }, + "initial_min_instance_count": { + "$id": "#/properties/schedules/properties/specific_date/items/properties/initial_min_instance_count", + "type": "integer", + "title": "The Initial_min_instance_count Schema" + } + } + } + } + } + } + }, + + "required": [ + "instance_min_count", + "instance_max_count" + ], + "anyOf": [ + { + "required": [ + "scaling_rules" + ] + }, + { + "required": [ + "schedules" + ] + } + ], + "additionalProperties": false +} diff --git a/src/autoscaler/api/binding_request/legacy_parser/json-structure.go b/src/autoscaler/api/binding_request/legacy_parser/json-structure.go new file mode 100644 index 0000000000..1b9b3c5410 --- /dev/null +++ b/src/autoscaler/api/binding_request/legacy_parser/json-structure.go @@ -0,0 +1,67 @@ +package legacy_parser + +import "code.cloudfoundry.org/app-autoscaler/src/autoscaler/models" + +type policyAndBindingCfg struct { + BindingConfig bindingConfig `json:"configuration"` + InstanceMin int `json:"instance_min_count"` + InstanceMax int `json:"instance_max_count"` + ScalingRules []*scalingRule `json:"scaling_rules,omitempty"` + Schedules *scalingSchedules `json:"schedules,omitempty"` +} + +// ================================================================================ +// Binding-configuration +// ================================================================================ + +type bindingConfig struct { + AppGUID models.GUID `json:"app_guid,omitempty"` // Empty value represents null-value (i.e. not set). + CustomMetrics customMetricsConfig `json:"custom_metrics,omitempty"` +} + +type customMetricsConfig struct { + MetricSubmissionStrategy metricsSubmissionStrategy `json:"metric_submission_strategy"` +} + +type metricsSubmissionStrategy struct { + AllowFrom string `json:"allow_from"` +} + +// ================================================================================ +// Scaling-policy details +// ================================================================================ + +type scalingRule struct { + MetricType string `json:"metric_type"` + BreachDurationSeconds int `json:"breach_duration_secs,omitempty"` + Threshold int64 `json:"threshold"` + Operator string `json:"operator"` + CoolDownSeconds int `json:"cool_down_secs,omitempty"` + Adjustment string `json:"adjustment"` +} + +type scalingSchedules struct { + Timezone string `json:"timezone"` + RecurringSchedules []*recurringSchedule `json:"recurring_schedule,omitempty"` + SpecificDateSchedules []*specificDateSchedule `json:"specific_date,omitempty"` +} + +type recurringSchedule struct { + StartTime string `json:"start_time"` + EndTime string `json:"end_time"` + DaysOfWeek []int `json:"days_of_week,omitempty"` + DaysOfMonth []int `json:"days_of_month,omitempty"` + StartDate string `json:"start_date,omitempty"` + EndDate string `json:"end_date,omitempty"` + ScheduledInstanceMin int `json:"instance_min_count"` + ScheduledInstanceMax int `json:"instance_max_count"` + ScheduledInstanceInit int `json:"initial_min_instance_count,omitempty"` +} + +type specificDateSchedule struct { + StartDateTime string `json:"start_date_time"` + EndDateTime string `json:"end_date_time"` + ScheduledInstanceMin int `json:"instance_min_count"` + ScheduledInstanceMax int `json:"instance_max_count"` + ScheduledInstanceInit int `json:"initial_min_instance_count,omitempty"` +} diff --git a/src/autoscaler/api/binding_request/legacy_parser/parser.go b/src/autoscaler/api/binding_request/legacy_parser/parser.go new file mode 100644 index 0000000000..0081304d3b --- /dev/null +++ b/src/autoscaler/api/binding_request/legacy_parser/parser.go @@ -0,0 +1,111 @@ +package legacy_parser + +import ( + "encoding/json" + + "github.com/xeipuuv/gojsonschema" + + "code.cloudfoundry.org/app-autoscaler/src/autoscaler/api/binding_request" + "code.cloudfoundry.org/app-autoscaler/src/autoscaler/models" +) + +type LegacyBindingRequestParser struct { + schema *gojsonschema.Schema +} + +var _ binding_request.Parser = LegacyBindingRequestParser{} + +func New() (LegacyBindingRequestParser, error) { + const schemaFilePath string = "file://./legacy-binding-request.json" + schemaLoader := gojsonschema.NewReferenceLoader(schemaFilePath) + schema, err := gojsonschema.NewSchema(schemaLoader) + if err != nil { + return LegacyBindingRequestParser{}, err + } + return LegacyBindingRequestParser{schema: schema}, nil +} + +func (p LegacyBindingRequestParser) Parse(bindingReqParams string) (binding_request.Parameters, error) { + documentLoader := gojsonschema.NewStringLoader(bindingReqParams) + validationResult, err := p.schema.Validate(documentLoader) + if err != nil { + // Defined by the implementation of `Validate`, this only happens, if the provided document + // (in this context `documentLoader`) can not be loaded. + return binding_request.Parameters{}, err + } else if !validationResult.Valid() { + // The error contains a description of all detected violations against the schema. + allErrors := binding_request.JsonSchemaError(validationResult.Errors()) + return binding_request.Parameters{}, allErrors + } + + var parsedParameters policyAndBindingCfg + err = json.Unmarshal([]byte(bindingReqParams), &parsedParameters) + if err != nil { + return binding_request.Parameters{}, err + } + + return toBindingParameters(parsedParameters), nil +} + +func toBindingParameters(params policyAndBindingCfg) binding_request.Parameters { + result := binding_request.Parameters{} + result.Configuration = &models.BindingConfig{ + AppGUID: models.GUID(params.BindingConfig.AppGUID), + CustomMetrics: &models.CustomMetricsConfig{ + MetricSubmissionStrategy: models.MetricsSubmissionStrategy{ + AllowFrom: params.BindingConfig.CustomMetrics.MetricSubmissionStrategy.AllowFrom, + }, + }, + } + + result.ScalingPolicy = &models.ScalingPolicy{ + InstanceMin: params.InstanceMin, + InstanceMax: params.InstanceMax, + } + + for _, rule := range params.ScalingRules { + scalingRule := &models.ScalingRule{ + MetricType: rule.MetricType, + BreachDurationSeconds: rule.BreachDurationSeconds, + Threshold: rule.Threshold, + Operator: rule.Operator, + CoolDownSeconds: rule.CoolDownSeconds, + Adjustment: rule.Adjustment, + } + result.ScalingPolicy.ScalingRules = append(result.ScalingPolicy.ScalingRules, scalingRule) + } + + if params.Schedules != nil { + result.ScalingPolicy.Schedules = &models.ScalingSchedules{ + Timezone: params.Schedules.Timezone, + } + + for _, recurring := range params.Schedules.RecurringSchedules { + recurringSchedule := &models.RecurringSchedule{ + StartTime: recurring.StartTime, + EndTime: recurring.EndTime, + DaysOfWeek: recurring.DaysOfWeek, + DaysOfMonth: recurring.DaysOfMonth, + StartDate: recurring.StartDate, + EndDate: recurring.EndDate, + ScheduledInstanceMin: recurring.ScheduledInstanceMin, + ScheduledInstanceMax: recurring.ScheduledInstanceMax, + ScheduledInstanceInit: recurring.ScheduledInstanceInit, + } + result.ScalingPolicy.Schedules.RecurringSchedules = append(result.ScalingPolicy.Schedules.RecurringSchedules, recurringSchedule) + } + + for _, specific := range params.Schedules.SpecificDateSchedules { + specificDateSchedule := &models.SpecificDateSchedule{ + StartDateTime: specific.StartDateTime, + EndDateTime: specific.EndDateTime, + ScheduledInstanceMin: specific.ScheduledInstanceMin, + ScheduledInstanceMax: specific.ScheduledInstanceMax, + ScheduledInstanceInit: specific.ScheduledInstanceInit, + } + result.ScalingPolicy.Schedules.SpecificDateSchedules = append(result.ScalingPolicy.Schedules.SpecificDateSchedules, specificDateSchedule) + } + } + + return result +} diff --git a/src/autoscaler/api/binding_request/shared_definitions.json b/src/autoscaler/api/binding_request/shared_definitions.json new file mode 120000 index 0000000000..e1fc4df59e --- /dev/null +++ b/src/autoscaler/api/binding_request/shared_definitions.json @@ -0,0 +1 @@ +../../../../schema/json/shared_definitions.json \ No newline at end of file From 3f362369ff8110e5c5207f4531e11afa43561e13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Weisbarth?= Date: Fri, 19 Sep 2025 17:17:50 +0200 Subject: [PATCH 02/20] Revert "Remove parts that belong rather to a different PR." This reverts commit 5b73c4fee604b2c897e62813947a72d171cf1962. --- schema/json/Readme.md | 3 + schema/json/app-scaling-configuration.json | 17 + schema/json/binding-configuration.json | 21 + schema/json/policy-configuration.json | 43 + schema/json/scaling-policy.json | 916 +++++++++++++++++++++ schema/json/shared_definitions.json | 10 + src/autoscaler/models/app.go | 87 +- 7 files changed, 1096 insertions(+), 1 deletion(-) create mode 100644 schema/json/Readme.md create mode 100644 schema/json/app-scaling-configuration.json create mode 100644 schema/json/binding-configuration.json create mode 100644 schema/json/policy-configuration.json create mode 100644 schema/json/scaling-policy.json create mode 100644 schema/json/shared_definitions.json diff --git a/schema/json/Readme.md b/schema/json/Readme.md new file mode 100644 index 0000000000..eec5278c3b --- /dev/null +++ b/schema/json/Readme.md @@ -0,0 +1,3 @@ +# Read-me # + +The currently used golang-library for json-schema, namely “[gojsonschema]()” not seems to be capable to resolve references to other files correctly across different directories. Perhaps not limited to but especially when referencing up the file-system-hierarchy (parent-directories). *Hint*: Use symbolic links to circumvent the issue! diff --git a/schema/json/app-scaling-configuration.json b/schema/json/app-scaling-configuration.json new file mode 100644 index 0000000000..56dc394b53 --- /dev/null +++ b/schema/json/app-scaling-configuration.json @@ -0,0 +1,17 @@ +{ + "$schema": "http://json-schema.org/draft-05/schema#", + "title": "Binding-request-parameters-schema", + "description": "Schema for parameters for a service-binding creation with an instances of Application Autoscaler.", + "type": "object", + + "properties": { + "binding-configuration": { + "$ref": "./binding-configuration.json" + }, + "scaling-policy": { + "$ref": "./scaling-policy.json" + } + }, + + "additionalProperties": false +} diff --git a/schema/json/binding-configuration.json b/schema/json/binding-configuration.json new file mode 100644 index 0000000000..14ac0e330d --- /dev/null +++ b/schema/json/binding-configuration.json @@ -0,0 +1,21 @@ +{ + "$schema": "http://json-schema.org/draft-05/schema#", + "title": "", + "description": "Schema for the configuration of service-bindings with instances of Application Autoscaler.", + "type": "object", + + "properties": { + "app_guid": { + "$ref": "./shared_definitions.json#/schemas/guid" + }, + "credential-type": { + "type": "string", + "enum": [ + "x509", + "binding-secret" + ], + } + }, + "required": ["app_guid"], + "additionalProperties": false +} diff --git a/schema/json/policy-configuration.json b/schema/json/policy-configuration.json new file mode 100644 index 0000000000..8d4d2b4dcb --- /dev/null +++ b/schema/json/policy-configuration.json @@ -0,0 +1,43 @@ +{ + "$schema": "http://json-schema.org/draft-05/schema#", + "title": "", + "description": "Schema for a scaling-policy.", + "type": "object", + + "properties": { + "configuration": { + "type": "object", + "properties": { + "custom_metrics": { + "type": "object", + "properties": { + "metric_submission_strategy": { + "type": "object", + "properties": { + "allow_from": { + "type": "string", + "enum": [ + "bound_app", + "same_app" + ] + } + }, + "required": [ + "allow_from" + ] + } + }, + "required": [ + "metric_submission_strategy" + ], + "additionalProperties": false + }, + }, + "required": [ + "custom_metrics" + ], + "additionalProperties": false + }, + }, + "additionalProperties": false +} diff --git a/schema/json/scaling-policy.json b/schema/json/scaling-policy.json new file mode 100644 index 0000000000..9a4b6e8308 --- /dev/null +++ b/schema/json/scaling-policy.json @@ -0,0 +1,916 @@ +{ + "$schema": "http://json-schema.org/draft-05/schema#", + "title": "Autoscaler Policy JSON Schema", + "description": "Schema for scaling-policies for Autoscaler", + "type": "object", + + "properties": { + "schema-version": { + "description": "Version-identifier for the used schema of this parameters-object.", + "type": "string", + "pattern": "^[0-9]+(\\.[0-9]+)?$" + }, + "configuration": { + "$ref": "./policy-configuration.json" + }, + "instance_min_count": { + "$id": "#/properties/instance_min_count", + "type": "integer", + "minimum": 1, + "title": "Minimum number of application instance always runs" + }, + "instance_max_count": { + "$id": "#/properties/instance_max_count", + "type": "integer", + "title": "Maximum how many instances of application can be provisioned as part of application scaling" + }, + "scaling_rules": { + "$id": "#/properties/scaling_rules", + "type": "array", + "title": "Dynamic Scaling_rules Schema", + "items": { + "$id": "#/properties/scaling_rules/items", + "type": "object", + "title": "Scaling_rules Items Schema", + "required": [ + "metric_type", + "threshold", + "operator", + "adjustment" + ], + "properties": { + "metric_type": { + "$id": "#/properties/scaling_rules/items/properties/metric_type", + "type": "string", + "title": "The Metric_type Schema", + "pattern": "^[a-zA-Z0-9_]+$", + "maxLength": 100 + }, + "breach_duration_secs": { + "$id": "#/properties/scaling_rules/items/properties/breach_duration_secs", + "type": "integer", + "title": "The Breach_duration_secs Schema", + "description": "The length of the past period when a scaling action might be triggered based on metric usage", + "maximum": 3600, + "minimum": 60 + }, + "threshold": { + "$id": "#/properties/scaling_rules/items/properties/threshold", + "type": "integer", + "title": "The Threshold Schema" + }, + "operator": { + "$id": "#/properties/scaling_rules/items/properties/operator", + "type": "string", + "title": "The Operator Schema", + "description": "Operator is used in combination with the threshold value to compare the current metric value", + "enum": [ + "<", + ">", + "<=", + ">=" + ] + }, + "cool_down_secs": { + "$id": "#/properties/scaling_rules/items/properties/cool_down_secs", + "type": "integer", + "title": "The Cool_down_secs Schema", + "description": "The interval between two successive scaling activity", + "maximum": 3600, + "minimum": 60 + }, + "adjustment": { + "$id": "#/properties/scaling_rules/items/properties/adjustment", + "type": "string", + "title": "The Adjustment Schema", + "description": "Magnitude of scaling in each step, +1 means scale up 1 Instance -2 means scale down 2 instances", + "pattern": "^[-+][1-9]+[0-9]*%?$" + } + } + } + }, + "schedules": { + "$id": "#/properties/schedules", + "type": "object", + "title": "The Scaling Schedules Schema", + "required": [ + "timezone" + ], + "anyOf": [ + { + "required": [ + "recurring_schedule" + ] + }, + { + "required": [ + "specific_date" + ] + } + ], + "properties": { + "timezone": { + "$id": "#/properties/schedules/properties/timezone", + "type": "string", + "title": "The Timezone Schema", + "pattern": "^(.*)$", + "enum": [ + "Etc/GMT+12", + "Etc/GMT+11", + "Pacific/Midway", + "Pacific/Niue", + "Pacific/Pago_Pago", + "Pacific/Samoa", + "US/Samoa", + "Etc/GMT+10", + "HST", + "Pacific/Honolulu", + "Pacific/Johnston", + "Pacific/Rarotonga", + "Pacific/Tahiti", + "US/Hawaii", + "Pacific/Marquesas", + "America/Adak", + "America/Atka", + "Etc/GMT+9", + "Pacific/Gambier", + "US/Aleutian", + "America/Anchorage", + "America/Juneau", + "America/Metlakatla", + "America/Nome", + "America/Sitka", + "America/Yakutat", + "Etc/GMT+8", + "Pacific/Pitcairn", + "US/Alaska", + "America/Creston", + "America/Dawson", + "America/Dawson_Creek", + "America/Ensenada", + "America/Hermosillo", + "America/Los_Angeles", + "America/Phoenix", + "America/Santa_Isabel", + "America/Tijuana", + "America/Vancouver", + "America/Whitehorse", + "Canada/Pacific", + "Canada/Yukon", + "Etc/GMT+7", + "MST", + "Mexico/BajaNorte", + "PST8PDT", + "US/Arizona", + "US/Pacific", + "US/Pacific-New", + "America/Belize", + "America/Boise", + "America/Cambridge_Bay", + "America/Chihuahua", + "America/Costa_Rica", + "America/Denver", + "America/Edmonton", + "America/El_Salvador", + "America/Guatemala", + "America/Inuvik", + "America/Managua", + "America/Mazatlan", + "America/Ojinaga", + "America/Regina", + "America/Shiprock", + "America/Swift_Current", + "America/Tegucigalpa", + "America/Yellowknife", + "Canada/East-Saskatchewan", + "Canada/Mountain", + "Canada/Saskatchewan", + "Etc/GMT+6", + "MST7MDT", + "Mexico/BajaSur", + "Navajo", + "Pacific/Galapagos", + "US/Mountain", + "America/Atikokan", + "America/Bahia_Banderas", + "America/Bogota", + "America/Cancun", + "America/Cayman", + "America/Chicago", + "America/Coral_Harbour", + "America/Eirunepe", + "America/Guayaquil", + "America/Indiana/Knox", + "America/Indiana/Tell_City", + "America/Jamaica", + "America/Knox_IN", + "America/Lima", + "America/Matamoros", + "America/Menominee", + "America/Merida", + "America/Mexico_City", + "America/Monterrey", + "America/North_Dakota/Beulah", + "America/North_Dakota/Center", + "America/North_Dakota/New_Salem", + "America/Panama", + "America/Porto_Acre", + "America/Rainy_River", + "America/Rankin_Inlet", + "America/Resolute", + "America/Rio_Branco", + "America/Winnipeg", + "Brazil/Acre", + "CST6CDT", + "Canada/Central", + "Chile/EasterIsland", + "EST", + "Etc/GMT+5", + "Jamaica", + "Mexico/General", + "Pacific/Easter", + "US/Central", + "US/Indiana-Starke", + "America/Caracas", + "America/Anguilla", + "America/Antigua", + "America/Aruba", + "America/Asuncion", + "America/Barbados", + "America/Blanc-Sablon", + "America/Boa_Vista", + "America/Campo_Grande", + "America/Cuiaba", + "America/Curacao", + "America/Detroit", + "America/Dominica", + "America/Fort_Wayne", + "America/Grand_Turk", + "America/Grenada", + "America/Guadeloupe", + "America/Guyana", + "America/Havana", + "America/Indiana/Indianapolis", + "America/Indiana/Marengo", + "America/Indiana/Petersburg", + "America/Indiana/Vevay", + "America/Indiana/Vincennes", + "America/Indiana/Winamac", + "America/Indianapolis", + "America/Iqaluit ", + "America/Kentucky/Louisville ", + "America/Kentucky/Monticello", + "America/Kralendijk", + "America/La_Paz", + "America/Louisville ", + "America/Lower_Princes", + "America/Manaus", + "America/Marigot", + "America/Martinique", + "America/Montreal", + "America/Montserrat", + "America/Nassau", + "America/New_York", + "America/Nipigon", + "America/Pangnirtung ", + "America/Port-au-Prince ", + "America/Port_of_Spain", + "America/Porto_Velho", + "America/Puerto_Rico ", + "America/Santo_Domingo ", + "America/St_Barthelemy", + "America/St_Kitts", + "America/St_Lucia", + "America/St_Thomas", + "America/St_Vincent", + "America/Thunder_Bay", + "America/Toronto", + "America/Tortola", + "America/Virgin", + "Brazil/West", + "Canada/Eastern", + "Cuba", + "EST5EDT", + "Etc/GMT+4", + "US/East-Indiana", + "US/Eastern", + "US/Michigan", + "America/Araguaina ", + "America/Argentina/Buenos_Aires ", + "America/Argentina/Catamarca ", + "America/Argentina/ComodRivadavia ", + "America/Argentina/Cordoba ", + "America/Argentina/Jujuy ", + "America/Argentina/La_Rioja ", + "America/Argentina/Mendoza ", + "America/Argentina/Rio_Gallegos ", + "America/Argentina/Salta ", + "America/Argentina/San_Juan ", + "America/Argentina/San_Luis ", + "America/Argentina/Tucuman ", + "America/Argentina/Ushuaia", + "America/Bahia", + "America/Belem", + "America/Buenos_Aires", + "America/Catamarca", + "America/Cayenne", + "America/Cordoba", + "America/Fortaleza", + "America/Glace_Bay", + "America/Goose_Bay", + "America/Halifax", + "America/Jujuy", + "America/Maceio", + "America/Mendoza", + "America/Moncton", + "America/Montevideo", + "America/Paramaribo", + "America/Recife", + "America/Rosario", + "America/Santarem", + "America/Santiago", + "America/Sao_Paulo", + "America/Thule", + "Antarctica/Palmer", + "Antarctica/Rothera", + "Atlantic/Bermuda", + "Atlantic/Stanley", + "Brazil/East", + "Canada/Atlantic", + "Chile/Continental", + "Etc/GMT+3", + "America/St_Johns", + "Canada/Newfoundland", + "America/Godthab", + "America/Miquelon", + "America/Noronha ", + "Atlantic/South_Georgia", + "Brazil/DeNoronha", + "Etc/GMT+2", + "Atlantic/Cape_Verde", + "Etc/GMT+1", + "Africa/Abidjan", + "Africa/Accra", + "Africa/Bamako", + "Africa/Banjul", + "Africa/Bissau", + "Africa/Conakry", + "Africa/Dakar", + "Africa/Freetown", + "Africa/Lome", + "Africa/Monrovia", + "Africa/Nouakchott", + "Africa/Ouagadougou", + "Africa/Sao_Tome", + "Africa/Timbuktu", + "America/Danmarkshavn", + "America/Scoresbysund", + "Atlantic/Azores", + "Atlantic/Reykjavik", + "Atlantic/St_Helena", + "Etc/GMT", + "Etc/GMT+0", + "Etc/GMT-0", + "Etc/GMT0", + "Etc/Greenwich", + "Etc/UCT", + "Etc/UTC", + "Etc/Universal", + "Etc/Zulu", + "GMT", + "GMT+0", + "GMT-0", + "GMT0", + "Greenwich", + "Iceland", + "UCT", + "UTC", + "Universal", + "Zulu", + "Africa/Algiers", + "Africa/Bangui", + "Africa/Brazzaville", + "Africa/Casablanca", + "Africa/Douala", + "Africa/El_Aaiun", + "Africa/Kinshasa", + "Africa/Lagos", + "Africa/Libreville", + "Africa/Luanda", + "Africa/Malabo", + "Africa/Ndjamena", + "Africa/Niamey", + "Africa/Porto-Novo", + "Africa/Tunis", + "Africa/Windhoek", + "Atlantic/Canary", + "Atlantic/Faeroe", + "Atlantic/Faroe", + "Atlantic/Madeira", + "Eire", + "Etc/GMT-1", + "Europe/Belfast", + "Europe/Dublin", + "Europe/Guernsey", + "Europe/Isle_of_Man", + "Europe/Jersey", + "Europe/Lisbon", + "Europe/London", + "GB", + "GB-Eire", + "Portugal", + "WET", + "Africa/Blantyre", + "Africa/Bujumbura", + "Africa/Cairo", + "Africa/Ceuta", + "Africa/Gaborone", + "Africa/Harare", + "Africa/Johannesburg", + "Africa/Kigali", + "Africa/Lubumbashi", + "Africa/Lusaka", + "Africa/Maputo", + "Africa/Maseru", + "Africa/Mbabane", + "Africa/Tripoli", + "Antarctica/Troll", + "Arctic/Longyearbyen", + "Atlantic/Jan_Mayen", + "CET", + "Egypt", + "Etc/GMT-2", + "Europe/Amsterdam", + "Europe/Andorra", + "Europe/Belgrade", + "Europe/Berlin", + "Europe/Bratislava", + "Europe/Brussels", + "Europe/Budapest", + "Europe/Busingen", + "Europe/Copenhagen", + "Europe/Gibraltar", + "Europe/Kaliningrad", + "Europe/Ljubljana", + "Europe/Luxembourg", + "Europe/Madrid", + "Europe/Malta", + "Europe/Monaco", + "Europe/Oslo", + "Europe/Paris", + "Europe/Podgorica", + "Europe/Prague", + "Europe/Rome", + "Europe/San_Marino", + "Europe/Sarajevo", + "Europe/Skopje", + "Europe/Stockholm", + "Europe/Tirane", + "Europe/Vaduz", + "Europe/Vatican", + "Europe/Vienna", + "Europe/Warsaw", + "Europe/Zagreb", + "Europe/Zurich", + "Libya", + "MET", + "Poland", + "Africa/Addis_Ababa", + "Africa/Asmara", + "Africa/Asmera", + "Africa/Dar_es_Salaam", + "Africa/Djibouti", + "Africa/Juba", + "Africa/Kampala", + "Africa/Khartoum", + "Africa/Mogadishu", + "Africa/Nairobi", + "Antarctica/Syowa", + "Asia/Aden", + "Asia/Amman", + "Asia/Baghdad", + "Asia/Bahrain", + "Asia/Beirut", + "Asia/Damascus", + "Asia/Gaza", + "Asia/Hebron", + "Asia/Istanbul", + "Asia/Jerusalem", + "Asia/Kuwait", + "Asia/Nicosia", + "Asia/Qatar", + "Asia/Riyadh", + "Asia/Tel_Aviv", + "EET", + "Etc/GMT-3", + "Europe/Athens", + "Europe/Bucharest", + "Europe/Chisinau", + "Europe/Helsinki", + "Europe/Istanbul", + "Europe/Kiev", + "Europe/Mariehamn", + "Europe/Minsk", + "Europe/Moscow", + "Europe/Nicosia", + "Europe/Riga", + "Europe/Simferopol", + "Europe/Sofia", + "Europe/Tallinn", + "Europe/Tiraspol", + "Europe/Uzhgorod", + "Europe/Vilnius", + "Europe/Volgograd", + "Europe/Zaporozhye", + "Indian/Antananarivo", + "Indian/Comoro", + "Indian/Mayotte", + "Israel", + "Turkey", + "W-SU", + "Asia/Dubai", + "Asia/Muscat", + "Asia/Tbilisi", + "Asia/Yerevan", + "Etc/GMT-4", + "Europe/Samara", + "Indian/Mahe", + "Indian/Mauritius", + "Indian/Reunion", + "Asia/Kabul", + "Asia/Tehran", + "Iran", + "Antarctica/Mawson", + "Asia/Aqtau", + "Asia/Aqtobe", + "Asia/Ashgabat", + "Asia/Ashkhabad", + "Asia/Baku", + "Asia/Dushanbe", + "Asia/Karachi", + "Asia/Oral", + "Asia/Samarkand", + "Asia/Tashkent", + "Asia/Yekaterinburg", + "Etc/GMT-5", + "Indian/Kerguelen", + "Indian/Maldives", + "Asia/Calcutta", + "Asia/Colombo", + "Asia/Kolkata", + "Asia/Kathmandu", + "Asia/Katmandu", + "Antarctica/Vostok", + "Asia/Almaty", + "Asia/Bishkek", + "Asia/Dacca", + "Asia/Dhaka", + "Asia/Kashgar", + "Asia/Novosibirsk", + "Asia/Omsk", + "Asia/Qyzylorda", + "Asia/Thimbu", + "Asia/Thimphu", + "Asia/Urumqi", + "Etc/GMT-6", + "Indian/Chagos", + "Asia/Rangoon", + "Indian/Cocos", + "Antarctica/Davis", + "Asia/Bangkok", + "Asia/Ho_Chi_Minh", + "Asia/Hovd", + "Asia/Jakarta", + "Asia/Krasnoyarsk", + "Asia/Novokuznetsk", + "Asia/Phnom_Penh", + "Asia/Pontianak", + "Asia/Saigon", + "Asia/Vientiane", + "Etc/GMT-7", + "Indian/Christmas", + "Antarctica/Casey", + "Asia/Brunei", + "Asia/Chita", + "Asia/Choibalsan", + "Asia/Chongqing", + "Asia/Chungking", + "Asia/Harbin", + "Asia/Hong_Kong", + "Asia/Irkutsk", + "Asia/Kuala_Lumpur", + "Asia/Kuching", + "Asia/Macao", + "Asia/Macau", + "Asia/Makassar", + "Asia/Manila", + "Asia/Shanghai", + "Asia/Singapore", + "Asia/Taipei", + "Asia/Ujung_Pandang", + "Asia/Ulaanbaatar", + "Asia/Ulan_Bator", + "Australia/Perth", + "Australia/West", + "Etc/GMT-8", + "Hongkong", + "PRC", + "ROC", + "Singapore", + "Australia/Eucla", + "Asia/Dili", + "Asia/Jayapura", + "Asia/Khandyga", + "Asia/Pyongyang", + "Asia/Seoul", + "Asia/Tokyo", + "Asia/Yakutsk", + "Etc/GMT-9", + "Japan", + "Pacific/Palau", + "ROK", + "Australia/Adelaide ", + "Australia/Broken_Hill", + "Australia/Darwin", + "Australia/North", + "Australia/South", + "Australia/Yancowinna ", + "Antarctica/DumontDUrville", + "Asia/Magadan", + "Asia/Sakhalin", + "Asia/Ust-Nera", + "Asia/Vladivostok", + "Australia/ACT", + "Australia/Brisbane", + "Australia/Canberra", + "Australia/Currie", + "Australia/Hobart", + "Australia/Lindeman", + "Australia/Melbourne", + "Australia/NSW", + "Australia/Queensland", + "Australia/Sydney", + "Australia/Tasmania", + "Australia/Victoria", + "Etc/GMT-10", + "Pacific/Chuuk", + "Pacific/Guam", + "Pacific/Port_Moresby", + "Pacific/Saipan", + "Pacific/Truk", + "Pacific/Yap", + "Australia/LHI", + "Australia/Lord_Howe", + "Antarctica/Macquarie", + "Asia/Srednekolymsk", + "Etc/GMT-11", + "Pacific/Bougainville", + "Pacific/Efate", + "Pacific/Guadalcanal", + "Pacific/Kosrae", + "Pacific/Noumea", + "Pacific/Pohnpei", + "Pacific/Ponape", + "Pacific/Norfolk", + "Antarctica/McMurdo", + "Antarctica/South_Pole", + "Asia/Anadyr", + "Asia/Kamchatka", + "Etc/GMT-12", + "Kwajalein", + "NZ", + "Pacific/Auckland", + "Pacific/Fiji", + "Pacific/Funafuti", + "Pacific/Kwajalein", + "Pacific/Majuro", + "Pacific/Nauru", + "Pacific/Tarawa", + "Pacific/Wake", + "Pacific/Wallis", + "NZ-CHAT", + "Pacific/Chatham", + "Etc/GMT-13", + "Pacific/Apia", + "Pacific/Enderbury", + "Pacific/Fakaofo", + "Pacific/Tongatapu", + "Etc/GMT-14", + "Pacific/Kiritimati" + ] + }, + "recurring_schedule": { + "$id": "#/properties/schedules/properties/recurring_schedule", + "type": "array", + "title": "The Recurring_schedule Schema", + "items": { + "$id": "#/properties/schedules/properties/recurring_schedule/items", + "type": "object", + "title": "The Recurring_schedule Items Schema", + "required": [ + "start_time", + "end_time", + "instance_min_count", + "instance_max_count" + ], + "oneOf": [ + { + "required": [ + "days_of_week" + ] + }, + { + "required": [ + "days_of_month" + ] + } + ], + "properties": { + "start_time": { + "$id": "#/properties/schedules/properties/recurring_schedule/items/properties/start_time", + "type": "string", + "title": "The Start_time Schema", + "pattern": "^(2[0-3]|1[0-9]|0[0-9]):([0-5][0-9])$" + }, + "end_time": { + "$id": "#/properties/schedules/properties/recurring_schedule/items/properties/end_time", + "type": "string", + "title": "The End_time Schema", + "pattern": "^(2[0-3]|1[0-9]|0[0-9]):([0-5][0-9])$" + }, + "days_of_week": { + "$id": "#/properties/schedules/properties/recurring_schedule/items/properties/days_of_week", + "type": "array", + "title": "The Days_of_week Schema", + "items": { + "$id": "#/properties/schedules/properties/recurring_schedule/items/properties/days_of_week/items", + "type": "integer", + "enum": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7 + ] + } + }, + "days_of_month": { + "$id": "#/properties/schedules/properties/recurring_schedule/items/properties/days_of_month", + "type": "array", + "title": "The Days_of_month Schema", + "items": { + "$id": "#/properties/schedules/properties/recurring_schedule/items/properties/days_of_month/items", + "type": "integer", + "enum": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31 + ] + } + }, + "instance_min_count": { + "$id": "#/properties/schedules/properties/recurring_schedule/items/properties/instance_min_count", + "type": "integer", + "title": "The Instance_min_count Schema" + }, + "instance_max_count": { + "$id": "#/properties/schedules/properties/recurring_schedule/items/properties/instance_max_count", + "type": "integer", + "title": "The Instance_max_count Schema" + }, + "initial_min_instance_count": { + "$id": "#/properties/schedules/properties/recurring_schedule/items/properties/initial_min_instance_count", + "type": "integer", + "title": "The Initial_min_instance_count Schema" + }, + "start_date": { + "oneOf": [ + { + "pattern": "^2[0-9]{3}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$", + "type": "string" + }, + { + "enum": [ + "" + ], + "type": "string" + } + ], + "description": "Start date of the recurrence in YYYY-MM-DD format" + }, + "end_date": { + "oneOf": [ + { + "pattern": "^2[0-9]{3}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$", + "type": "string" + }, + { + "enum": [ + "" + ], + "type": "string" + } + ], + "description": "End date of the recurrence in YYYY-MM-DD format" + } + } + } + }, + "specific_date": { + "$id": "#/properties/schedules/properties/specific_date", + "type": "array", + "title": "The Specific_date Schema", + "items": { + "$id": "#/properties/schedules/properties/specific_date/items", + "type": "object", + "title": "The Items Schema", + "required": [ + "start_date_time", + "end_date_time", + "instance_min_count", + "instance_max_count" + ], + "properties": { + "start_date_time": { + "$id": "#/properties/schedules/properties/specific_date/items/properties/start_date_time", + "type": "string", + "title": "The Start_date_time Schema", + "pattern": "^2[0-9]{3}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])T(2[0-3]|1[0-9]|0[0-9]):([0-5][0-9])$" + }, + "end_date_time": { + "$id": "#/properties/schedules/properties/specific_date/items/properties/end_date_time", + "type": "string", + "title": "The End_date_time Schema", + "default": "", + "pattern": "^2[0-9]{3}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])T(2[0-3]|1[0-9]|0[0-9]):([0-5][0-9])$" + }, + "instance_min_count": { + "$id": "#/properties/schedules/properties/specific_date/items/properties/instance_min_count", + "type": "integer", + "title": "The Instance_min_count Schema" + }, + "instance_max_count": { + "$id": "#/properties/schedules/properties/specific_date/items/properties/instance_max_count", + "type": "integer", + "title": "The Instance_max_count Schema" + }, + "initial_min_instance_count": { + "$id": "#/properties/schedules/properties/specific_date/items/properties/initial_min_instance_count", + "type": "integer", + "title": "The Initial_min_instance_count Schema" + } + } + } + } + } + } + }, + + "required": [ + "instance_min_count", + "instance_max_count" + ], + "anyOf": [ + { + "required": [ + "scaling_rules" + ] + }, + { + "required": [ + "schedules" + ] + } + ], + "additionalProperties": false +} diff --git a/schema/json/shared_definitions.json b/schema/json/shared_definitions.json new file mode 100644 index 0000000000..46a6ae9315 --- /dev/null +++ b/schema/json/shared_definitions.json @@ -0,0 +1,10 @@ +{ + "schemas": { + "guid": { + "type": "string", + "description": "Unique identificator for a CF-resource, e.g. app, space, service-binding, …", + "pattern": "(\\d|[a-f]){8}-(\\d|[a-f]){4}-(\\d|[a-f]){4}-(\\d|[a-f]){4}-(\\d|[a-f]){12}", + "example": "8d0cee08-23ad-4813-a779-ad8118ea0b91" + } + } +} diff --git a/src/autoscaler/models/app.go b/src/autoscaler/models/app.go index af145ab125..8ebfa5a4c7 100644 --- a/src/autoscaler/models/app.go +++ b/src/autoscaler/models/app.go @@ -1,6 +1,13 @@ package models -import "time" +import ( + "encoding/json" + "errors" + "fmt" + "os" + "regexp" + "time" +) type ScalingType int type ScalingStatus int @@ -45,3 +52,81 @@ type AppScalingResult struct { Adjustment int `json:"adjustment"` CooldownExpiredAt int64 `json:"cool_down_expired_at"` } + +// 🚧 To-do: Bring this in line with the content of “models/common_typges.go”. +// ================================================================================ +// GUIDs +// ================================================================================ + +// Globally unique identifier in the context of a “Cloud Foundry” installation; +type CfGuid string + +func (g CfGuid) String() string { + return string(g) +} + +type CfGuidParser struct { + regexp *regexp.Regexp +} + +func NewCfGuidParser() CfGuidParser { + filePath := "../../../schema/json/shared_definitions.json" + jsonData, err := os.ReadFile(filePath) + if err != nil { + errMsg := fmt.Errorf("could not read file \"%s\"\nError: %w", filePath, err) + // Panicing here is O.K. because it does not make sense to launch autoscaler because it has + // been shipped with an invalid (or non-existent) file that should contain a json-schema. + panic(fmt.Sprintf( + "%s\nThis is a programming-error as the file must be on the hardcoded location.", + errMsg)) + } + + // Unfortunately there is no ordinary library comparable to + // e.g. that allows to parse arbitrary JSON without + // defining homomorphic structs in the host-language. So here comes a type that describes the + // structure of the file `…/shared_definitions.json` (see above) with the sole intention to read + // out the content of the field `pattern`. + type Schema struct { + Schemas struct { + Guid struct { + Pattern string `json:"pattern"` + } `json:"guid"` + } `json:"schemas"` + } + var schema Schema + err = json.Unmarshal(jsonData, &schema) + if err != nil { + errMsg := fmt.Errorf("could not unmarshal JSON from file \"%s\"\nError: %w", filePath, err) + // Panicing here is O.K. because it does not make sense to launch autoscaler because it has + // been shipped with an file with invalid json-code. + panic(fmt.Sprintf( + "%s\nThis is a programming-error as the local Schema-struct must match roughly the file-structure.", + errMsg)) + } + pattern := schema.Schemas.Guid.Pattern + + r, err := regexp.CompilePOSIX(pattern) + if err != nil { + // Panicing here is O.K. because it does not make sense to launch autoscaler because it has + // been shipped with an invalid json-schema. + panic(`The provided pattern is invalid. +This is a programming-error as the pattern must be a valid POSIX-regexp.`) + } + + return CfGuidParser{regexp: r} +} + +func (p CfGuidParser) Parse(rawGuid string) (CfGuid, error) { + matched := p.regexp.MatchString(rawGuid) + if !matched { + msg := fmt.Sprintf("The provided string does not look like a Cloud Foundry GUID: %s", rawGuid) + return "", errors.New(msg) + } + + return CfGuid(rawGuid), nil +} + +func ParseGuid(rawGuid string) (CfGuid, error) { + p := NewCfGuidParser() + return p.Parse(rawGuid) +} From cff73489b78a4393958865bce3d853b81133e86e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Weisbarth?= Date: Tue, 30 Sep 2025 16:01:19 +0200 Subject: [PATCH 03/20] =?UTF-8?q?=F0=9F=94=A7=20Fix=20schemas;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- schema/json/binding-configuration.json | 2 +- schema/json/policy-configuration.json | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/schema/json/binding-configuration.json b/schema/json/binding-configuration.json index 14ac0e330d..6c6288c590 100644 --- a/schema/json/binding-configuration.json +++ b/schema/json/binding-configuration.json @@ -13,7 +13,7 @@ "enum": [ "x509", "binding-secret" - ], + ] } }, "required": ["app_guid"], diff --git a/schema/json/policy-configuration.json b/schema/json/policy-configuration.json index 8d4d2b4dcb..983f5f1afc 100644 --- a/schema/json/policy-configuration.json +++ b/schema/json/policy-configuration.json @@ -31,13 +31,13 @@ "metric_submission_strategy" ], "additionalProperties": false - }, + } }, "required": [ "custom_metrics" ], "additionalProperties": false - }, + } }, "additionalProperties": false } From eac69f9afd693a2ed52465f62b63f80e93c5dd4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Weisbarth?= Date: Tue, 30 Sep 2025 16:41:32 +0200 Subject: [PATCH 04/20] Introduce new schema-naming-convention and remove legacy-schema; --- ... => app-scaling-configuration.schema.json} | 4 +- ...json => binding-configuration.schema.json} | 0 .../policy-configuration.legacy-schema.json | 53 + ....json => policy-configuration.schema.json} | 0 .../json/scaling-policy.legacy-schema.json | 13 +- ...policy.json => scaling-policy.schema.json} | 2 +- .../app-scaling-configuration.schema.json | 1 + .../binding_request/autoscaler-policy.json | 1 - .../binding-configuration.json | 1 - .../binding-configuration.schema.json | 1 + .../api/binding_request/binding-request.json | 1 - .../policy-configuration.legacy-schema.json | 1 + .../policy-configuration.schema.json | 1 + .../scaling-policy.legacy-schema.json | 1 + .../scaling-policy.schema.json | 1 + .../policyvalidator/policy_json.schema.json | 932 ------------------ 16 files changed, 71 insertions(+), 942 deletions(-) rename schema/json/{app-scaling-configuration.json => app-scaling-configuration.schema.json} (79%) rename schema/json/{binding-configuration.json => binding-configuration.schema.json} (100%) create mode 100644 schema/json/policy-configuration.legacy-schema.json rename schema/json/{policy-configuration.json => policy-configuration.schema.json} (100%) rename src/autoscaler/api/binding_request/legacy-binding-request.json => schema/json/scaling-policy.legacy-schema.json (98%) rename schema/json/{scaling-policy.json => scaling-policy.schema.json} (99%) create mode 120000 src/autoscaler/api/binding_request/app-scaling-configuration.schema.json delete mode 120000 src/autoscaler/api/binding_request/autoscaler-policy.json delete mode 120000 src/autoscaler/api/binding_request/binding-configuration.json create mode 120000 src/autoscaler/api/binding_request/binding-configuration.schema.json delete mode 120000 src/autoscaler/api/binding_request/binding-request.json create mode 120000 src/autoscaler/api/binding_request/policy-configuration.legacy-schema.json create mode 120000 src/autoscaler/api/binding_request/policy-configuration.schema.json create mode 120000 src/autoscaler/api/binding_request/scaling-policy.legacy-schema.json create mode 120000 src/autoscaler/api/binding_request/scaling-policy.schema.json delete mode 100644 src/autoscaler/api/policyvalidator/policy_json.schema.json diff --git a/schema/json/app-scaling-configuration.json b/schema/json/app-scaling-configuration.schema.json similarity index 79% rename from schema/json/app-scaling-configuration.json rename to schema/json/app-scaling-configuration.schema.json index 56dc394b53..8bfecf2397 100644 --- a/schema/json/app-scaling-configuration.json +++ b/schema/json/app-scaling-configuration.schema.json @@ -6,10 +6,10 @@ "properties": { "binding-configuration": { - "$ref": "./binding-configuration.json" + "$ref": "./binding-configuration.schema.json" }, "scaling-policy": { - "$ref": "./scaling-policy.json" + "$ref": "./scaling-policy.schema.json" } }, diff --git a/schema/json/binding-configuration.json b/schema/json/binding-configuration.schema.json similarity index 100% rename from schema/json/binding-configuration.json rename to schema/json/binding-configuration.schema.json diff --git a/schema/json/policy-configuration.legacy-schema.json b/schema/json/policy-configuration.legacy-schema.json new file mode 100644 index 0000000000..dda9ff9d92 --- /dev/null +++ b/schema/json/policy-configuration.legacy-schema.json @@ -0,0 +1,53 @@ +{ + "$schema": "http://json-schema.org/draft-05/schema#", + "title": "", + "description": "Schema for a scaling-policy.", + "type": "object", + + "properties": { + "configuration": { + "type": "object", + "properties": { + "custom_metrics": { + "type": "object", + "properties": { + "metric_submission_strategy": { + "type": "object", + "properties": { + "allow_from": { + "type": "string", + "enum": [ + "bound_app", + "same_app" + ] + } + }, + "required": [ + "allow_from" + ] + } + }, + "required": [ + "metric_submission_strategy" + ], + "additionalProperties": false + }, + "app_guid": { + "$ref": "./shared_definitions.json#/schemas/guid" + }, + "credential-type": { + "type": "string", + "enum": [ + "x509", + "binding-secret" + ] + } + }, + "required": [ + "custom_metrics" + ], + "additionalProperties": false + } + }, + "additionalProperties": false +} diff --git a/schema/json/policy-configuration.json b/schema/json/policy-configuration.schema.json similarity index 100% rename from schema/json/policy-configuration.json rename to schema/json/policy-configuration.schema.json diff --git a/src/autoscaler/api/binding_request/legacy-binding-request.json b/schema/json/scaling-policy.legacy-schema.json similarity index 98% rename from src/autoscaler/api/binding_request/legacy-binding-request.json rename to schema/json/scaling-policy.legacy-schema.json index d3c889875d..e3d2e8cc59 100644 --- a/src/autoscaler/api/binding_request/legacy-binding-request.json +++ b/schema/json/scaling-policy.legacy-schema.json @@ -1,12 +1,17 @@ { "$schema": "http://json-schema.org/draft-05/schema#", - "title": "", - "description": "Legacy schema for the combination of a scaling-policy and the configuration of service-bindings with instances of Application Autoscaler.", + "title": "Autoscaler Policy JSON Schema", + "description": "Schema for scaling-policies for Autoscaler", "type": "object", "properties": { + "schema-version": { + "description": "Version-identifier for the used schema of this parameters-object.", + "type": "string", + "pattern": "^[0-9]+(\\.[0-9]+)?$" + }, "configuration": { - "$ref": "./binding-configuration.json" + "$ref": "./policy-configuration.legacy-schema.json" }, "instance_min_count": { "$id": "#/properties/instance_min_count", @@ -17,7 +22,7 @@ "instance_max_count": { "$id": "#/properties/instance_max_count", "type": "integer", - "title": "Maximum how many instances of application can be provisioned as part o f application scaling" + "title": "Maximum how many instances of application can be provisioned as part of application scaling" }, "scaling_rules": { "$id": "#/properties/scaling_rules", diff --git a/schema/json/scaling-policy.json b/schema/json/scaling-policy.schema.json similarity index 99% rename from schema/json/scaling-policy.json rename to schema/json/scaling-policy.schema.json index 9a4b6e8308..04f61a1657 100644 --- a/schema/json/scaling-policy.json +++ b/schema/json/scaling-policy.schema.json @@ -11,7 +11,7 @@ "pattern": "^[0-9]+(\\.[0-9]+)?$" }, "configuration": { - "$ref": "./policy-configuration.json" + "$ref": "./policy-configuration.schema.json" }, "instance_min_count": { "$id": "#/properties/instance_min_count", diff --git a/src/autoscaler/api/binding_request/app-scaling-configuration.schema.json b/src/autoscaler/api/binding_request/app-scaling-configuration.schema.json new file mode 120000 index 0000000000..bd4df4ede2 --- /dev/null +++ b/src/autoscaler/api/binding_request/app-scaling-configuration.schema.json @@ -0,0 +1 @@ +../../../../schema/json/app-scaling-configuration.schema.json \ No newline at end of file diff --git a/src/autoscaler/api/binding_request/autoscaler-policy.json b/src/autoscaler/api/binding_request/autoscaler-policy.json deleted file mode 120000 index c684b4a64e..0000000000 --- a/src/autoscaler/api/binding_request/autoscaler-policy.json +++ /dev/null @@ -1 +0,0 @@ -../../../../schema/json/autoscaler-policy.json \ No newline at end of file diff --git a/src/autoscaler/api/binding_request/binding-configuration.json b/src/autoscaler/api/binding_request/binding-configuration.json deleted file mode 120000 index 7a02de2ce5..0000000000 --- a/src/autoscaler/api/binding_request/binding-configuration.json +++ /dev/null @@ -1 +0,0 @@ -../../../../schema/json/binding-configuration.json \ No newline at end of file diff --git a/src/autoscaler/api/binding_request/binding-configuration.schema.json b/src/autoscaler/api/binding_request/binding-configuration.schema.json new file mode 120000 index 0000000000..4c8af3a4bb --- /dev/null +++ b/src/autoscaler/api/binding_request/binding-configuration.schema.json @@ -0,0 +1 @@ +../../../../schema/json/binding-configuration.schema.json \ No newline at end of file diff --git a/src/autoscaler/api/binding_request/binding-request.json b/src/autoscaler/api/binding_request/binding-request.json deleted file mode 120000 index 588a0dc2f7..0000000000 --- a/src/autoscaler/api/binding_request/binding-request.json +++ /dev/null @@ -1 +0,0 @@ -../../../../schema/json/binding-request.json \ No newline at end of file diff --git a/src/autoscaler/api/binding_request/policy-configuration.legacy-schema.json b/src/autoscaler/api/binding_request/policy-configuration.legacy-schema.json new file mode 120000 index 0000000000..c754806e59 --- /dev/null +++ b/src/autoscaler/api/binding_request/policy-configuration.legacy-schema.json @@ -0,0 +1 @@ +../../../../schema/json/policy-configuration.legacy-schema.json \ No newline at end of file diff --git a/src/autoscaler/api/binding_request/policy-configuration.schema.json b/src/autoscaler/api/binding_request/policy-configuration.schema.json new file mode 120000 index 0000000000..48ce660b34 --- /dev/null +++ b/src/autoscaler/api/binding_request/policy-configuration.schema.json @@ -0,0 +1 @@ +../../../../schema/json/policy-configuration.schema.json \ No newline at end of file diff --git a/src/autoscaler/api/binding_request/scaling-policy.legacy-schema.json b/src/autoscaler/api/binding_request/scaling-policy.legacy-schema.json new file mode 120000 index 0000000000..98ca85b397 --- /dev/null +++ b/src/autoscaler/api/binding_request/scaling-policy.legacy-schema.json @@ -0,0 +1 @@ +../../../../schema/json/scaling-policy.legacy-schema.json \ No newline at end of file diff --git a/src/autoscaler/api/binding_request/scaling-policy.schema.json b/src/autoscaler/api/binding_request/scaling-policy.schema.json new file mode 120000 index 0000000000..e50dc96b9d --- /dev/null +++ b/src/autoscaler/api/binding_request/scaling-policy.schema.json @@ -0,0 +1 @@ +../../../../schema/json/scaling-policy.schema.json \ No newline at end of file diff --git a/src/autoscaler/api/policyvalidator/policy_json.schema.json b/src/autoscaler/api/policyvalidator/policy_json.schema.json deleted file mode 100644 index 0c1e0a1e45..0000000000 --- a/src/autoscaler/api/policyvalidator/policy_json.schema.json +++ /dev/null @@ -1,932 +0,0 @@ -{ - "definitions": {}, - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "title": "Autoscaler Policy JSON Schema", - "required": [ - "instance_min_count", - "instance_max_count" - ], - "anyOf": [ - { - "required": [ - "scaling_rules" - ] - }, - { - "required": [ - "schedules" - ] - } - ], - "properties": { - "configuration": { - "type": "object", - "properties": { - "custom_metrics": { - "type": "object", - "properties": { - "metric_submission_strategy": { - "type": "object", - "properties": { - "allow_from": { - "type": "string", - "enum": [ - "bound_app" - ] - } - }, - "required": [ - "allow_from" - ] - } - }, - "required": [ - "metric_submission_strategy" - ] - } - } - }, - "instance_min_count": { - "$id": "#/properties/instance_min_count", - "type": "integer", - "minimum": 1, - "title": "Minimum number of application instance always runs" - }, - "instance_max_count": { - "$id": "#/properties/instance_max_count", - "type": "integer", - "title": "Maximum how many instances of application can be provisioned as part of application scaling" - }, - "scaling_rules": { - "$id": "#/properties/scaling_rules", - "type": "array", - "title": "Dynamic Scaling_rules Schema", - "items": { - "$id": "#/properties/scaling_rules/items", - "type": "object", - "title": "Scaling_rules Items Schema", - "required": [ - "metric_type", - "threshold", - "operator", - "adjustment" - ], - "properties": { - "metric_type": { - "$id": "#/properties/scaling_rules/items/properties/metric_type", - "type": "string", - "title": "The Metric_type Schema", - "pattern": "^[a-zA-Z0-9_]+$", - "maxLength": 100 - }, - "breach_duration_secs": { - "$id": "#/properties/scaling_rules/items/properties/breach_duration_secs", - "type": "integer", - "title": "The Breach_duration_secs Schema", - "description": "The length of the past period when a scaling action might be triggered based on metric usage", - "maximum": 3600, - "minimum": 60 - }, - "threshold": { - "$id": "#/properties/scaling_rules/items/properties/threshold", - "type": "integer", - "title": "The Threshold Schema" - }, - "operator": { - "$id": "#/properties/scaling_rules/items/properties/operator", - "type": "string", - "title": "The Operator Schema", - "description": "Operator is used in combination with the threshold value to compare the current metric value", - "enum": [ - "<", - ">", - "<=", - ">=" - ] - }, - "cool_down_secs": { - "$id": "#/properties/scaling_rules/items/properties/cool_down_secs", - "type": "integer", - "title": "The Cool_down_secs Schema", - "description": "The interval between two successive scaling activity", - "maximum": 3600, - "minimum": 60 - }, - "adjustment": { - "$id": "#/properties/scaling_rules/items/properties/adjustment", - "type": "string", - "title": "The Adjustment Schema", - "description": "Magnitude of scaling in each step, +1 means scale up 1 Instance -2 means scale down 2 instances", - "pattern": "^[-+][1-9]+[0-9]*%?$" - } - } - } - }, - "schedules": { - "$id": "#/properties/schedules", - "type": "object", - "title": "The Scaling Schedules Schema", - "required": [ - "timezone" - ], - "anyOf": [ - { - "required": [ - "recurring_schedule" - ] - }, - { - "required": [ - "specific_date" - ] - } - ], - "properties": { - "timezone": { - "$id": "#/properties/schedules/properties/timezone", - "type": "string", - "title": "The Timezone Schema", - "pattern": "^(.*)$", - "enum": [ - "Etc/GMT+12", - "Etc/GMT+11", - "Pacific/Midway", - "Pacific/Niue", - "Pacific/Pago_Pago", - "Pacific/Samoa", - "US/Samoa", - "Etc/GMT+10", - "HST", - "Pacific/Honolulu", - "Pacific/Johnston", - "Pacific/Rarotonga", - "Pacific/Tahiti", - "US/Hawaii", - "Pacific/Marquesas", - "America/Adak", - "America/Atka", - "Etc/GMT+9", - "Pacific/Gambier", - "US/Aleutian", - "America/Anchorage", - "America/Juneau", - "America/Metlakatla", - "America/Nome", - "America/Sitka", - "America/Yakutat", - "Etc/GMT+8", - "Pacific/Pitcairn", - "US/Alaska", - "America/Creston", - "America/Dawson", - "America/Dawson_Creek", - "America/Ensenada", - "America/Hermosillo", - "America/Los_Angeles", - "America/Phoenix", - "America/Santa_Isabel", - "America/Tijuana", - "America/Vancouver", - "America/Whitehorse", - "Canada/Pacific", - "Canada/Yukon", - "Etc/GMT+7", - "MST", - "Mexico/BajaNorte", - "PST8PDT", - "US/Arizona", - "US/Pacific", - "US/Pacific-New", - "America/Belize", - "America/Boise", - "America/Cambridge_Bay", - "America/Chihuahua", - "America/Costa_Rica", - "America/Denver", - "America/Edmonton", - "America/El_Salvador", - "America/Guatemala", - "America/Inuvik", - "America/Managua", - "America/Mazatlan", - "America/Ojinaga", - "America/Regina", - "America/Shiprock", - "America/Swift_Current", - "America/Tegucigalpa", - "America/Yellowknife", - "Canada/East-Saskatchewan", - "Canada/Mountain", - "Canada/Saskatchewan", - "Etc/GMT+6", - "MST7MDT", - "Mexico/BajaSur", - "Navajo", - "Pacific/Galapagos", - "US/Mountain", - "America/Atikokan", - "America/Bahia_Banderas", - "America/Bogota", - "America/Cancun", - "America/Cayman", - "America/Chicago", - "America/Coral_Harbour", - "America/Eirunepe", - "America/Guayaquil", - "America/Indiana/Knox", - "America/Indiana/Tell_City", - "America/Jamaica", - "America/Knox_IN", - "America/Lima", - "America/Matamoros", - "America/Menominee", - "America/Merida", - "America/Mexico_City", - "America/Monterrey", - "America/North_Dakota/Beulah", - "America/North_Dakota/Center", - "America/North_Dakota/New_Salem", - "America/Panama", - "America/Porto_Acre", - "America/Rainy_River", - "America/Rankin_Inlet", - "America/Resolute", - "America/Rio_Branco", - "America/Winnipeg", - "Brazil/Acre", - "CST6CDT", - "Canada/Central", - "Chile/EasterIsland", - "EST", - "Etc/GMT+5", - "Jamaica", - "Mexico/General", - "Pacific/Easter", - "US/Central", - "US/Indiana-Starke", - "America/Caracas", - "America/Anguilla", - "America/Antigua", - "America/Aruba", - "America/Asuncion", - "America/Barbados", - "America/Blanc-Sablon", - "America/Boa_Vista", - "America/Campo_Grande", - "America/Cuiaba", - "America/Curacao", - "America/Detroit", - "America/Dominica", - "America/Fort_Wayne", - "America/Grand_Turk", - "America/Grenada", - "America/Guadeloupe", - "America/Guyana", - "America/Havana", - "America/Indiana/Indianapolis", - "America/Indiana/Marengo", - "America/Indiana/Petersburg", - "America/Indiana/Vevay", - "America/Indiana/Vincennes", - "America/Indiana/Winamac", - "America/Indianapolis", - "America/Iqaluit ", - "America/Kentucky/Louisville ", - "America/Kentucky/Monticello", - "America/Kralendijk", - "America/La_Paz", - "America/Louisville ", - "America/Lower_Princes", - "America/Manaus", - "America/Marigot", - "America/Martinique", - "America/Montreal", - "America/Montserrat", - "America/Nassau", - "America/New_York", - "America/Nipigon", - "America/Pangnirtung ", - "America/Port-au-Prince ", - "America/Port_of_Spain", - "America/Porto_Velho", - "America/Puerto_Rico ", - "America/Santo_Domingo ", - "America/St_Barthelemy", - "America/St_Kitts", - "America/St_Lucia", - "America/St_Thomas", - "America/St_Vincent", - "America/Thunder_Bay", - "America/Toronto", - "America/Tortola", - "America/Virgin", - "Brazil/West", - "Canada/Eastern", - "Cuba", - "EST5EDT", - "Etc/GMT+4", - "US/East-Indiana", - "US/Eastern", - "US/Michigan", - "America/Araguaina ", - "America/Argentina/Buenos_Aires ", - "America/Argentina/Catamarca ", - "America/Argentina/ComodRivadavia ", - "America/Argentina/Cordoba ", - "America/Argentina/Jujuy ", - "America/Argentina/La_Rioja ", - "America/Argentina/Mendoza ", - "America/Argentina/Rio_Gallegos ", - "America/Argentina/Salta ", - "America/Argentina/San_Juan ", - "America/Argentina/San_Luis ", - "America/Argentina/Tucuman ", - "America/Argentina/Ushuaia", - "America/Bahia", - "America/Belem", - "America/Buenos_Aires", - "America/Catamarca", - "America/Cayenne", - "America/Cordoba", - "America/Fortaleza", - "America/Glace_Bay", - "America/Goose_Bay", - "America/Halifax", - "America/Jujuy", - "America/Maceio", - "America/Mendoza", - "America/Moncton", - "America/Montevideo", - "America/Paramaribo", - "America/Recife", - "America/Rosario", - "America/Santarem", - "America/Santiago", - "America/Sao_Paulo", - "America/Thule", - "Antarctica/Palmer", - "Antarctica/Rothera", - "Atlantic/Bermuda", - "Atlantic/Stanley", - "Brazil/East", - "Canada/Atlantic", - "Chile/Continental", - "Etc/GMT+3", - "America/St_Johns", - "Canada/Newfoundland", - "America/Godthab", - "America/Miquelon", - "America/Noronha ", - "Atlantic/South_Georgia", - "Brazil/DeNoronha", - "Etc/GMT+2", - "Atlantic/Cape_Verde", - "Etc/GMT+1", - "Africa/Abidjan", - "Africa/Accra", - "Africa/Bamako", - "Africa/Banjul", - "Africa/Bissau", - "Africa/Conakry", - "Africa/Dakar", - "Africa/Freetown", - "Africa/Lome", - "Africa/Monrovia", - "Africa/Nouakchott", - "Africa/Ouagadougou", - "Africa/Sao_Tome", - "Africa/Timbuktu", - "America/Danmarkshavn", - "America/Scoresbysund", - "Atlantic/Azores", - "Atlantic/Reykjavik", - "Atlantic/St_Helena", - "Etc/GMT", - "Etc/GMT+0", - "Etc/GMT-0", - "Etc/GMT0", - "Etc/Greenwich", - "Etc/UCT", - "Etc/UTC", - "Etc/Universal", - "Etc/Zulu", - "GMT", - "GMT+0", - "GMT-0", - "GMT0", - "Greenwich", - "Iceland", - "UCT", - "UTC", - "Universal", - "Zulu", - "Africa/Algiers", - "Africa/Bangui", - "Africa/Brazzaville", - "Africa/Casablanca", - "Africa/Douala", - "Africa/El_Aaiun", - "Africa/Kinshasa", - "Africa/Lagos", - "Africa/Libreville", - "Africa/Luanda", - "Africa/Malabo", - "Africa/Ndjamena", - "Africa/Niamey", - "Africa/Porto-Novo", - "Africa/Tunis", - "Africa/Windhoek", - "Atlantic/Canary", - "Atlantic/Faeroe", - "Atlantic/Faroe", - "Atlantic/Madeira", - "Eire", - "Etc/GMT-1", - "Europe/Belfast", - "Europe/Dublin", - "Europe/Guernsey", - "Europe/Isle_of_Man", - "Europe/Jersey", - "Europe/Lisbon", - "Europe/London", - "GB", - "GB-Eire", - "Portugal", - "WET", - "Africa/Blantyre", - "Africa/Bujumbura", - "Africa/Cairo", - "Africa/Ceuta", - "Africa/Gaborone", - "Africa/Harare", - "Africa/Johannesburg", - "Africa/Kigali", - "Africa/Lubumbashi", - "Africa/Lusaka", - "Africa/Maputo", - "Africa/Maseru", - "Africa/Mbabane", - "Africa/Tripoli", - "Antarctica/Troll", - "Arctic/Longyearbyen", - "Atlantic/Jan_Mayen", - "CET", - "Egypt", - "Etc/GMT-2", - "Europe/Amsterdam", - "Europe/Andorra", - "Europe/Belgrade", - "Europe/Berlin", - "Europe/Bratislava", - "Europe/Brussels", - "Europe/Budapest", - "Europe/Busingen", - "Europe/Copenhagen", - "Europe/Gibraltar", - "Europe/Kaliningrad", - "Europe/Ljubljana", - "Europe/Luxembourg", - "Europe/Madrid", - "Europe/Malta", - "Europe/Monaco", - "Europe/Oslo", - "Europe/Paris", - "Europe/Podgorica", - "Europe/Prague", - "Europe/Rome", - "Europe/San_Marino", - "Europe/Sarajevo", - "Europe/Skopje", - "Europe/Stockholm", - "Europe/Tirane", - "Europe/Vaduz", - "Europe/Vatican", - "Europe/Vienna", - "Europe/Warsaw", - "Europe/Zagreb", - "Europe/Zurich", - "Libya", - "MET", - "Poland", - "Africa/Addis_Ababa", - "Africa/Asmara", - "Africa/Asmera", - "Africa/Dar_es_Salaam", - "Africa/Djibouti", - "Africa/Juba", - "Africa/Kampala", - "Africa/Khartoum", - "Africa/Mogadishu", - "Africa/Nairobi", - "Antarctica/Syowa", - "Asia/Aden", - "Asia/Amman", - "Asia/Baghdad", - "Asia/Bahrain", - "Asia/Beirut", - "Asia/Damascus", - "Asia/Gaza", - "Asia/Hebron", - "Asia/Istanbul", - "Asia/Jerusalem", - "Asia/Kuwait", - "Asia/Nicosia", - "Asia/Qatar", - "Asia/Riyadh", - "Asia/Tel_Aviv", - "EET", - "Etc/GMT-3", - "Europe/Athens", - "Europe/Bucharest", - "Europe/Chisinau", - "Europe/Helsinki", - "Europe/Istanbul", - "Europe/Kiev", - "Europe/Mariehamn", - "Europe/Minsk", - "Europe/Moscow", - "Europe/Nicosia", - "Europe/Riga", - "Europe/Simferopol", - "Europe/Sofia", - "Europe/Tallinn", - "Europe/Tiraspol", - "Europe/Uzhgorod", - "Europe/Vilnius", - "Europe/Volgograd", - "Europe/Zaporozhye", - "Indian/Antananarivo", - "Indian/Comoro", - "Indian/Mayotte", - "Israel", - "Turkey", - "W-SU", - "Asia/Dubai", - "Asia/Muscat", - "Asia/Tbilisi", - "Asia/Yerevan", - "Etc/GMT-4", - "Europe/Samara", - "Indian/Mahe", - "Indian/Mauritius", - "Indian/Reunion", - "Asia/Kabul", - "Asia/Tehran", - "Iran", - "Antarctica/Mawson", - "Asia/Aqtau", - "Asia/Aqtobe", - "Asia/Ashgabat", - "Asia/Ashkhabad", - "Asia/Baku", - "Asia/Dushanbe", - "Asia/Karachi", - "Asia/Oral", - "Asia/Samarkand", - "Asia/Tashkent", - "Asia/Yekaterinburg", - "Etc/GMT-5", - "Indian/Kerguelen", - "Indian/Maldives", - "Asia/Calcutta", - "Asia/Colombo", - "Asia/Kolkata", - "Asia/Kathmandu", - "Asia/Katmandu", - "Antarctica/Vostok", - "Asia/Almaty", - "Asia/Bishkek", - "Asia/Dacca", - "Asia/Dhaka", - "Asia/Kashgar", - "Asia/Novosibirsk", - "Asia/Omsk", - "Asia/Qyzylorda", - "Asia/Thimbu", - "Asia/Thimphu", - "Asia/Urumqi", - "Etc/GMT-6", - "Indian/Chagos", - "Asia/Rangoon", - "Indian/Cocos", - "Antarctica/Davis", - "Asia/Bangkok", - "Asia/Ho_Chi_Minh", - "Asia/Hovd", - "Asia/Jakarta", - "Asia/Krasnoyarsk", - "Asia/Novokuznetsk", - "Asia/Phnom_Penh", - "Asia/Pontianak", - "Asia/Saigon", - "Asia/Vientiane", - "Etc/GMT-7", - "Indian/Christmas", - "Antarctica/Casey", - "Asia/Brunei", - "Asia/Chita", - "Asia/Choibalsan", - "Asia/Chongqing", - "Asia/Chungking", - "Asia/Harbin", - "Asia/Hong_Kong", - "Asia/Irkutsk", - "Asia/Kuala_Lumpur", - "Asia/Kuching", - "Asia/Macao", - "Asia/Macau", - "Asia/Makassar", - "Asia/Manila", - "Asia/Shanghai", - "Asia/Singapore", - "Asia/Taipei", - "Asia/Ujung_Pandang", - "Asia/Ulaanbaatar", - "Asia/Ulan_Bator", - "Australia/Perth", - "Australia/West", - "Etc/GMT-8", - "Hongkong", - "PRC", - "ROC", - "Singapore", - "Australia/Eucla", - "Asia/Dili", - "Asia/Jayapura", - "Asia/Khandyga", - "Asia/Pyongyang", - "Asia/Seoul", - "Asia/Tokyo", - "Asia/Yakutsk", - "Etc/GMT-9", - "Japan", - "Pacific/Palau", - "ROK", - "Australia/Adelaide ", - "Australia/Broken_Hill", - "Australia/Darwin", - "Australia/North", - "Australia/South", - "Australia/Yancowinna ", - "Antarctica/DumontDUrville", - "Asia/Magadan", - "Asia/Sakhalin", - "Asia/Ust-Nera", - "Asia/Vladivostok", - "Australia/ACT", - "Australia/Brisbane", - "Australia/Canberra", - "Australia/Currie", - "Australia/Hobart", - "Australia/Lindeman", - "Australia/Melbourne", - "Australia/NSW", - "Australia/Queensland", - "Australia/Sydney", - "Australia/Tasmania", - "Australia/Victoria", - "Etc/GMT-10", - "Pacific/Chuuk", - "Pacific/Guam", - "Pacific/Port_Moresby", - "Pacific/Saipan", - "Pacific/Truk", - "Pacific/Yap", - "Australia/LHI", - "Australia/Lord_Howe", - "Antarctica/Macquarie", - "Asia/Srednekolymsk", - "Etc/GMT-11", - "Pacific/Bougainville", - "Pacific/Efate", - "Pacific/Guadalcanal", - "Pacific/Kosrae", - "Pacific/Noumea", - "Pacific/Pohnpei", - "Pacific/Ponape", - "Pacific/Norfolk", - "Antarctica/McMurdo", - "Antarctica/South_Pole", - "Asia/Anadyr", - "Asia/Kamchatka", - "Etc/GMT-12", - "Kwajalein", - "NZ", - "Pacific/Auckland", - "Pacific/Fiji", - "Pacific/Funafuti", - "Pacific/Kwajalein", - "Pacific/Majuro", - "Pacific/Nauru", - "Pacific/Tarawa", - "Pacific/Wake", - "Pacific/Wallis", - "NZ-CHAT", - "Pacific/Chatham", - "Etc/GMT-13", - "Pacific/Apia", - "Pacific/Enderbury", - "Pacific/Fakaofo", - "Pacific/Tongatapu", - "Etc/GMT-14", - "Pacific/Kiritimati" - ] - }, - "recurring_schedule": { - "$id": "#/properties/schedules/properties/recurring_schedule", - "type": "array", - "title": "The Recurring_schedule Schema", - "items": { - "$id": "#/properties/schedules/properties/recurring_schedule/items", - "type": "object", - "title": "The Recurring_schedule Items Schema", - "required": [ - "start_time", - "end_time", - "instance_min_count", - "instance_max_count" - ], - "oneOf": [ - { - "required": [ - "days_of_week" - ] - }, - { - "required": [ - "days_of_month" - ] - } - ], - "properties": { - "start_time": { - "$id": "#/properties/schedules/properties/recurring_schedule/items/properties/start_time", - "type": "string", - "title": "The Start_time Schema", - "pattern": "^(2[0-3]|1[0-9]|0[0-9]):([0-5][0-9])$" - }, - "end_time": { - "$id": "#/properties/schedules/properties/recurring_schedule/items/properties/end_time", - "type": "string", - "title": "The End_time Schema", - "pattern": "^(2[0-3]|1[0-9]|0[0-9]):([0-5][0-9])$" - }, - "days_of_week": { - "$id": "#/properties/schedules/properties/recurring_schedule/items/properties/days_of_week", - "type": "array", - "title": "The Days_of_week Schema", - "items": { - "$id": "#/properties/schedules/properties/recurring_schedule/items/properties/days_of_week/items", - "type": "integer", - "enum": [ - 1, - 2, - 3, - 4, - 5, - 6, - 7 - ] - } - }, - "days_of_month": { - "$id": "#/properties/schedules/properties/recurring_schedule/items/properties/days_of_month", - "type": "array", - "title": "The Days_of_month Schema", - "items": { - "$id": "#/properties/schedules/properties/recurring_schedule/items/properties/days_of_month/items", - "type": "integer", - "enum": [ - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20, - 21, - 22, - 23, - 24, - 25, - 26, - 27, - 28, - 29, - 30, - 31 - ] - } - }, - "instance_min_count": { - "$id": "#/properties/schedules/properties/recurring_schedule/items/properties/instance_min_count", - "type": "integer", - "title": "The Instance_min_count Schema" - }, - "instance_max_count": { - "$id": "#/properties/schedules/properties/recurring_schedule/items/properties/instance_max_count", - "type": "integer", - "title": "The Instance_max_count Schema" - }, - "initial_min_instance_count": { - "$id": "#/properties/schedules/properties/recurring_schedule/items/properties/initial_min_instance_count", - "type": "integer", - "title": "The Initial_min_instance_count Schema" - }, - "start_date": { - "oneOf": [ - { - "pattern": "^2[0-9]{3}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$", - "type": "string" - }, - { - "enum": [ - "" - ], - "type": "string" - } - ], - "description": "Start date of the recurrence in YYYY-MM-DD format" - }, - "end_date": { - "oneOf": [ - { - "pattern": "^2[0-9]{3}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$", - "type": "string" - }, - { - "enum": [ - "" - ], - "type": "string" - } - ], - "description": "End date of the recurrence in YYYY-MM-DD format" - } - } - } - }, - "specific_date": { - "$id": "#/properties/schedules/properties/specific_date", - "type": "array", - "title": "The Specific_date Schema", - "items": { - "$id": "#/properties/schedules/properties/specific_date/items", - "type": "object", - "title": "The Items Schema", - "required": [ - "start_date_time", - "end_date_time", - "instance_min_count", - "instance_max_count" - ], - "properties": { - "start_date_time": { - "$id": "#/properties/schedules/properties/specific_date/items/properties/start_date_time", - "type": "string", - "title": "The Start_date_time Schema", - "pattern": "^2[0-9]{3}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])T(2[0-3]|1[0-9]|0[0-9]):([0-5][0-9])$" - }, - "end_date_time": { - "$id": "#/properties/schedules/properties/specific_date/items/properties/end_date_time", - "type": "string", - "title": "The End_date_time Schema", - "default": "", - "pattern": "^2[0-9]{3}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])T(2[0-3]|1[0-9]|0[0-9]):([0-5][0-9])$" - }, - "instance_min_count": { - "$id": "#/properties/schedules/properties/specific_date/items/properties/instance_min_count", - "type": "integer", - "title": "The Instance_min_count Schema" - }, - "instance_max_count": { - "$id": "#/properties/schedules/properties/specific_date/items/properties/instance_max_count", - "type": "integer", - "title": "The Instance_max_count Schema" - }, - "initial_min_instance_count": { - "$id": "#/properties/schedules/properties/specific_date/items/properties/initial_min_instance_count", - "type": "integer", - "title": "The Initial_min_instance_count Schema" - } - } - } - } - } - } - } -} From 5f5127b7883e947322039b47cceb89d7082c9053 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Weisbarth?= Date: Tue, 30 Sep 2025 17:20:44 +0200 Subject: [PATCH 05/20] Faktor out schema (to different PR); --- .../app-scaling-configuration.schema.json | 17 - schema/json/binding-configuration.schema.json | 21 - schema/json/policy-configuration.schema.json | 43 - schema/json/scaling-policy.schema.json | 916 ------------------ .../app-scaling-configuration.schema.json | 1 - .../binding-configuration.schema.json | 1 - .../binding_request/binding-request-parser.go | 32 - .../binding-request-parser_suite_test.go | 13 - .../binding-request-parser_test.go | 172 ---- .../clean_parser/json-structure.go | 70 -- .../binding_request/clean_parser/parser.go | 128 --- .../binding_request/combined_parser/parser.go | 35 - .../legacy_parser/json-structure.go | 67 -- .../binding_request/legacy_parser/parser.go | 111 --- .../policy-configuration.legacy-schema.json | 1 - .../policy-configuration.schema.json | 1 - .../scaling-policy.legacy-schema.json | 1 - .../scaling-policy.schema.json | 1 - .../binding_request/shared_definitions.json | 1 - 19 files changed, 1632 deletions(-) delete mode 100644 schema/json/app-scaling-configuration.schema.json delete mode 100644 schema/json/binding-configuration.schema.json delete mode 100644 schema/json/policy-configuration.schema.json delete mode 100644 schema/json/scaling-policy.schema.json delete mode 120000 src/autoscaler/api/binding_request/app-scaling-configuration.schema.json delete mode 120000 src/autoscaler/api/binding_request/binding-configuration.schema.json delete mode 100644 src/autoscaler/api/binding_request/binding-request-parser.go delete mode 100644 src/autoscaler/api/binding_request/binding-request-parser_suite_test.go delete mode 100644 src/autoscaler/api/binding_request/binding-request-parser_test.go delete mode 100644 src/autoscaler/api/binding_request/clean_parser/json-structure.go delete mode 100644 src/autoscaler/api/binding_request/clean_parser/parser.go delete mode 100644 src/autoscaler/api/binding_request/combined_parser/parser.go delete mode 100644 src/autoscaler/api/binding_request/legacy_parser/json-structure.go delete mode 100644 src/autoscaler/api/binding_request/legacy_parser/parser.go delete mode 120000 src/autoscaler/api/binding_request/policy-configuration.legacy-schema.json delete mode 120000 src/autoscaler/api/binding_request/policy-configuration.schema.json delete mode 120000 src/autoscaler/api/binding_request/scaling-policy.legacy-schema.json delete mode 120000 src/autoscaler/api/binding_request/scaling-policy.schema.json delete mode 120000 src/autoscaler/api/binding_request/shared_definitions.json diff --git a/schema/json/app-scaling-configuration.schema.json b/schema/json/app-scaling-configuration.schema.json deleted file mode 100644 index 8bfecf2397..0000000000 --- a/schema/json/app-scaling-configuration.schema.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-05/schema#", - "title": "Binding-request-parameters-schema", - "description": "Schema for parameters for a service-binding creation with an instances of Application Autoscaler.", - "type": "object", - - "properties": { - "binding-configuration": { - "$ref": "./binding-configuration.schema.json" - }, - "scaling-policy": { - "$ref": "./scaling-policy.schema.json" - } - }, - - "additionalProperties": false -} diff --git a/schema/json/binding-configuration.schema.json b/schema/json/binding-configuration.schema.json deleted file mode 100644 index 6c6288c590..0000000000 --- a/schema/json/binding-configuration.schema.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-05/schema#", - "title": "", - "description": "Schema for the configuration of service-bindings with instances of Application Autoscaler.", - "type": "object", - - "properties": { - "app_guid": { - "$ref": "./shared_definitions.json#/schemas/guid" - }, - "credential-type": { - "type": "string", - "enum": [ - "x509", - "binding-secret" - ] - } - }, - "required": ["app_guid"], - "additionalProperties": false -} diff --git a/schema/json/policy-configuration.schema.json b/schema/json/policy-configuration.schema.json deleted file mode 100644 index 983f5f1afc..0000000000 --- a/schema/json/policy-configuration.schema.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-05/schema#", - "title": "", - "description": "Schema for a scaling-policy.", - "type": "object", - - "properties": { - "configuration": { - "type": "object", - "properties": { - "custom_metrics": { - "type": "object", - "properties": { - "metric_submission_strategy": { - "type": "object", - "properties": { - "allow_from": { - "type": "string", - "enum": [ - "bound_app", - "same_app" - ] - } - }, - "required": [ - "allow_from" - ] - } - }, - "required": [ - "metric_submission_strategy" - ], - "additionalProperties": false - } - }, - "required": [ - "custom_metrics" - ], - "additionalProperties": false - } - }, - "additionalProperties": false -} diff --git a/schema/json/scaling-policy.schema.json b/schema/json/scaling-policy.schema.json deleted file mode 100644 index 04f61a1657..0000000000 --- a/schema/json/scaling-policy.schema.json +++ /dev/null @@ -1,916 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-05/schema#", - "title": "Autoscaler Policy JSON Schema", - "description": "Schema for scaling-policies for Autoscaler", - "type": "object", - - "properties": { - "schema-version": { - "description": "Version-identifier for the used schema of this parameters-object.", - "type": "string", - "pattern": "^[0-9]+(\\.[0-9]+)?$" - }, - "configuration": { - "$ref": "./policy-configuration.schema.json" - }, - "instance_min_count": { - "$id": "#/properties/instance_min_count", - "type": "integer", - "minimum": 1, - "title": "Minimum number of application instance always runs" - }, - "instance_max_count": { - "$id": "#/properties/instance_max_count", - "type": "integer", - "title": "Maximum how many instances of application can be provisioned as part of application scaling" - }, - "scaling_rules": { - "$id": "#/properties/scaling_rules", - "type": "array", - "title": "Dynamic Scaling_rules Schema", - "items": { - "$id": "#/properties/scaling_rules/items", - "type": "object", - "title": "Scaling_rules Items Schema", - "required": [ - "metric_type", - "threshold", - "operator", - "adjustment" - ], - "properties": { - "metric_type": { - "$id": "#/properties/scaling_rules/items/properties/metric_type", - "type": "string", - "title": "The Metric_type Schema", - "pattern": "^[a-zA-Z0-9_]+$", - "maxLength": 100 - }, - "breach_duration_secs": { - "$id": "#/properties/scaling_rules/items/properties/breach_duration_secs", - "type": "integer", - "title": "The Breach_duration_secs Schema", - "description": "The length of the past period when a scaling action might be triggered based on metric usage", - "maximum": 3600, - "minimum": 60 - }, - "threshold": { - "$id": "#/properties/scaling_rules/items/properties/threshold", - "type": "integer", - "title": "The Threshold Schema" - }, - "operator": { - "$id": "#/properties/scaling_rules/items/properties/operator", - "type": "string", - "title": "The Operator Schema", - "description": "Operator is used in combination with the threshold value to compare the current metric value", - "enum": [ - "<", - ">", - "<=", - ">=" - ] - }, - "cool_down_secs": { - "$id": "#/properties/scaling_rules/items/properties/cool_down_secs", - "type": "integer", - "title": "The Cool_down_secs Schema", - "description": "The interval between two successive scaling activity", - "maximum": 3600, - "minimum": 60 - }, - "adjustment": { - "$id": "#/properties/scaling_rules/items/properties/adjustment", - "type": "string", - "title": "The Adjustment Schema", - "description": "Magnitude of scaling in each step, +1 means scale up 1 Instance -2 means scale down 2 instances", - "pattern": "^[-+][1-9]+[0-9]*%?$" - } - } - } - }, - "schedules": { - "$id": "#/properties/schedules", - "type": "object", - "title": "The Scaling Schedules Schema", - "required": [ - "timezone" - ], - "anyOf": [ - { - "required": [ - "recurring_schedule" - ] - }, - { - "required": [ - "specific_date" - ] - } - ], - "properties": { - "timezone": { - "$id": "#/properties/schedules/properties/timezone", - "type": "string", - "title": "The Timezone Schema", - "pattern": "^(.*)$", - "enum": [ - "Etc/GMT+12", - "Etc/GMT+11", - "Pacific/Midway", - "Pacific/Niue", - "Pacific/Pago_Pago", - "Pacific/Samoa", - "US/Samoa", - "Etc/GMT+10", - "HST", - "Pacific/Honolulu", - "Pacific/Johnston", - "Pacific/Rarotonga", - "Pacific/Tahiti", - "US/Hawaii", - "Pacific/Marquesas", - "America/Adak", - "America/Atka", - "Etc/GMT+9", - "Pacific/Gambier", - "US/Aleutian", - "America/Anchorage", - "America/Juneau", - "America/Metlakatla", - "America/Nome", - "America/Sitka", - "America/Yakutat", - "Etc/GMT+8", - "Pacific/Pitcairn", - "US/Alaska", - "America/Creston", - "America/Dawson", - "America/Dawson_Creek", - "America/Ensenada", - "America/Hermosillo", - "America/Los_Angeles", - "America/Phoenix", - "America/Santa_Isabel", - "America/Tijuana", - "America/Vancouver", - "America/Whitehorse", - "Canada/Pacific", - "Canada/Yukon", - "Etc/GMT+7", - "MST", - "Mexico/BajaNorte", - "PST8PDT", - "US/Arizona", - "US/Pacific", - "US/Pacific-New", - "America/Belize", - "America/Boise", - "America/Cambridge_Bay", - "America/Chihuahua", - "America/Costa_Rica", - "America/Denver", - "America/Edmonton", - "America/El_Salvador", - "America/Guatemala", - "America/Inuvik", - "America/Managua", - "America/Mazatlan", - "America/Ojinaga", - "America/Regina", - "America/Shiprock", - "America/Swift_Current", - "America/Tegucigalpa", - "America/Yellowknife", - "Canada/East-Saskatchewan", - "Canada/Mountain", - "Canada/Saskatchewan", - "Etc/GMT+6", - "MST7MDT", - "Mexico/BajaSur", - "Navajo", - "Pacific/Galapagos", - "US/Mountain", - "America/Atikokan", - "America/Bahia_Banderas", - "America/Bogota", - "America/Cancun", - "America/Cayman", - "America/Chicago", - "America/Coral_Harbour", - "America/Eirunepe", - "America/Guayaquil", - "America/Indiana/Knox", - "America/Indiana/Tell_City", - "America/Jamaica", - "America/Knox_IN", - "America/Lima", - "America/Matamoros", - "America/Menominee", - "America/Merida", - "America/Mexico_City", - "America/Monterrey", - "America/North_Dakota/Beulah", - "America/North_Dakota/Center", - "America/North_Dakota/New_Salem", - "America/Panama", - "America/Porto_Acre", - "America/Rainy_River", - "America/Rankin_Inlet", - "America/Resolute", - "America/Rio_Branco", - "America/Winnipeg", - "Brazil/Acre", - "CST6CDT", - "Canada/Central", - "Chile/EasterIsland", - "EST", - "Etc/GMT+5", - "Jamaica", - "Mexico/General", - "Pacific/Easter", - "US/Central", - "US/Indiana-Starke", - "America/Caracas", - "America/Anguilla", - "America/Antigua", - "America/Aruba", - "America/Asuncion", - "America/Barbados", - "America/Blanc-Sablon", - "America/Boa_Vista", - "America/Campo_Grande", - "America/Cuiaba", - "America/Curacao", - "America/Detroit", - "America/Dominica", - "America/Fort_Wayne", - "America/Grand_Turk", - "America/Grenada", - "America/Guadeloupe", - "America/Guyana", - "America/Havana", - "America/Indiana/Indianapolis", - "America/Indiana/Marengo", - "America/Indiana/Petersburg", - "America/Indiana/Vevay", - "America/Indiana/Vincennes", - "America/Indiana/Winamac", - "America/Indianapolis", - "America/Iqaluit ", - "America/Kentucky/Louisville ", - "America/Kentucky/Monticello", - "America/Kralendijk", - "America/La_Paz", - "America/Louisville ", - "America/Lower_Princes", - "America/Manaus", - "America/Marigot", - "America/Martinique", - "America/Montreal", - "America/Montserrat", - "America/Nassau", - "America/New_York", - "America/Nipigon", - "America/Pangnirtung ", - "America/Port-au-Prince ", - "America/Port_of_Spain", - "America/Porto_Velho", - "America/Puerto_Rico ", - "America/Santo_Domingo ", - "America/St_Barthelemy", - "America/St_Kitts", - "America/St_Lucia", - "America/St_Thomas", - "America/St_Vincent", - "America/Thunder_Bay", - "America/Toronto", - "America/Tortola", - "America/Virgin", - "Brazil/West", - "Canada/Eastern", - "Cuba", - "EST5EDT", - "Etc/GMT+4", - "US/East-Indiana", - "US/Eastern", - "US/Michigan", - "America/Araguaina ", - "America/Argentina/Buenos_Aires ", - "America/Argentina/Catamarca ", - "America/Argentina/ComodRivadavia ", - "America/Argentina/Cordoba ", - "America/Argentina/Jujuy ", - "America/Argentina/La_Rioja ", - "America/Argentina/Mendoza ", - "America/Argentina/Rio_Gallegos ", - "America/Argentina/Salta ", - "America/Argentina/San_Juan ", - "America/Argentina/San_Luis ", - "America/Argentina/Tucuman ", - "America/Argentina/Ushuaia", - "America/Bahia", - "America/Belem", - "America/Buenos_Aires", - "America/Catamarca", - "America/Cayenne", - "America/Cordoba", - "America/Fortaleza", - "America/Glace_Bay", - "America/Goose_Bay", - "America/Halifax", - "America/Jujuy", - "America/Maceio", - "America/Mendoza", - "America/Moncton", - "America/Montevideo", - "America/Paramaribo", - "America/Recife", - "America/Rosario", - "America/Santarem", - "America/Santiago", - "America/Sao_Paulo", - "America/Thule", - "Antarctica/Palmer", - "Antarctica/Rothera", - "Atlantic/Bermuda", - "Atlantic/Stanley", - "Brazil/East", - "Canada/Atlantic", - "Chile/Continental", - "Etc/GMT+3", - "America/St_Johns", - "Canada/Newfoundland", - "America/Godthab", - "America/Miquelon", - "America/Noronha ", - "Atlantic/South_Georgia", - "Brazil/DeNoronha", - "Etc/GMT+2", - "Atlantic/Cape_Verde", - "Etc/GMT+1", - "Africa/Abidjan", - "Africa/Accra", - "Africa/Bamako", - "Africa/Banjul", - "Africa/Bissau", - "Africa/Conakry", - "Africa/Dakar", - "Africa/Freetown", - "Africa/Lome", - "Africa/Monrovia", - "Africa/Nouakchott", - "Africa/Ouagadougou", - "Africa/Sao_Tome", - "Africa/Timbuktu", - "America/Danmarkshavn", - "America/Scoresbysund", - "Atlantic/Azores", - "Atlantic/Reykjavik", - "Atlantic/St_Helena", - "Etc/GMT", - "Etc/GMT+0", - "Etc/GMT-0", - "Etc/GMT0", - "Etc/Greenwich", - "Etc/UCT", - "Etc/UTC", - "Etc/Universal", - "Etc/Zulu", - "GMT", - "GMT+0", - "GMT-0", - "GMT0", - "Greenwich", - "Iceland", - "UCT", - "UTC", - "Universal", - "Zulu", - "Africa/Algiers", - "Africa/Bangui", - "Africa/Brazzaville", - "Africa/Casablanca", - "Africa/Douala", - "Africa/El_Aaiun", - "Africa/Kinshasa", - "Africa/Lagos", - "Africa/Libreville", - "Africa/Luanda", - "Africa/Malabo", - "Africa/Ndjamena", - "Africa/Niamey", - "Africa/Porto-Novo", - "Africa/Tunis", - "Africa/Windhoek", - "Atlantic/Canary", - "Atlantic/Faeroe", - "Atlantic/Faroe", - "Atlantic/Madeira", - "Eire", - "Etc/GMT-1", - "Europe/Belfast", - "Europe/Dublin", - "Europe/Guernsey", - "Europe/Isle_of_Man", - "Europe/Jersey", - "Europe/Lisbon", - "Europe/London", - "GB", - "GB-Eire", - "Portugal", - "WET", - "Africa/Blantyre", - "Africa/Bujumbura", - "Africa/Cairo", - "Africa/Ceuta", - "Africa/Gaborone", - "Africa/Harare", - "Africa/Johannesburg", - "Africa/Kigali", - "Africa/Lubumbashi", - "Africa/Lusaka", - "Africa/Maputo", - "Africa/Maseru", - "Africa/Mbabane", - "Africa/Tripoli", - "Antarctica/Troll", - "Arctic/Longyearbyen", - "Atlantic/Jan_Mayen", - "CET", - "Egypt", - "Etc/GMT-2", - "Europe/Amsterdam", - "Europe/Andorra", - "Europe/Belgrade", - "Europe/Berlin", - "Europe/Bratislava", - "Europe/Brussels", - "Europe/Budapest", - "Europe/Busingen", - "Europe/Copenhagen", - "Europe/Gibraltar", - "Europe/Kaliningrad", - "Europe/Ljubljana", - "Europe/Luxembourg", - "Europe/Madrid", - "Europe/Malta", - "Europe/Monaco", - "Europe/Oslo", - "Europe/Paris", - "Europe/Podgorica", - "Europe/Prague", - "Europe/Rome", - "Europe/San_Marino", - "Europe/Sarajevo", - "Europe/Skopje", - "Europe/Stockholm", - "Europe/Tirane", - "Europe/Vaduz", - "Europe/Vatican", - "Europe/Vienna", - "Europe/Warsaw", - "Europe/Zagreb", - "Europe/Zurich", - "Libya", - "MET", - "Poland", - "Africa/Addis_Ababa", - "Africa/Asmara", - "Africa/Asmera", - "Africa/Dar_es_Salaam", - "Africa/Djibouti", - "Africa/Juba", - "Africa/Kampala", - "Africa/Khartoum", - "Africa/Mogadishu", - "Africa/Nairobi", - "Antarctica/Syowa", - "Asia/Aden", - "Asia/Amman", - "Asia/Baghdad", - "Asia/Bahrain", - "Asia/Beirut", - "Asia/Damascus", - "Asia/Gaza", - "Asia/Hebron", - "Asia/Istanbul", - "Asia/Jerusalem", - "Asia/Kuwait", - "Asia/Nicosia", - "Asia/Qatar", - "Asia/Riyadh", - "Asia/Tel_Aviv", - "EET", - "Etc/GMT-3", - "Europe/Athens", - "Europe/Bucharest", - "Europe/Chisinau", - "Europe/Helsinki", - "Europe/Istanbul", - "Europe/Kiev", - "Europe/Mariehamn", - "Europe/Minsk", - "Europe/Moscow", - "Europe/Nicosia", - "Europe/Riga", - "Europe/Simferopol", - "Europe/Sofia", - "Europe/Tallinn", - "Europe/Tiraspol", - "Europe/Uzhgorod", - "Europe/Vilnius", - "Europe/Volgograd", - "Europe/Zaporozhye", - "Indian/Antananarivo", - "Indian/Comoro", - "Indian/Mayotte", - "Israel", - "Turkey", - "W-SU", - "Asia/Dubai", - "Asia/Muscat", - "Asia/Tbilisi", - "Asia/Yerevan", - "Etc/GMT-4", - "Europe/Samara", - "Indian/Mahe", - "Indian/Mauritius", - "Indian/Reunion", - "Asia/Kabul", - "Asia/Tehran", - "Iran", - "Antarctica/Mawson", - "Asia/Aqtau", - "Asia/Aqtobe", - "Asia/Ashgabat", - "Asia/Ashkhabad", - "Asia/Baku", - "Asia/Dushanbe", - "Asia/Karachi", - "Asia/Oral", - "Asia/Samarkand", - "Asia/Tashkent", - "Asia/Yekaterinburg", - "Etc/GMT-5", - "Indian/Kerguelen", - "Indian/Maldives", - "Asia/Calcutta", - "Asia/Colombo", - "Asia/Kolkata", - "Asia/Kathmandu", - "Asia/Katmandu", - "Antarctica/Vostok", - "Asia/Almaty", - "Asia/Bishkek", - "Asia/Dacca", - "Asia/Dhaka", - "Asia/Kashgar", - "Asia/Novosibirsk", - "Asia/Omsk", - "Asia/Qyzylorda", - "Asia/Thimbu", - "Asia/Thimphu", - "Asia/Urumqi", - "Etc/GMT-6", - "Indian/Chagos", - "Asia/Rangoon", - "Indian/Cocos", - "Antarctica/Davis", - "Asia/Bangkok", - "Asia/Ho_Chi_Minh", - "Asia/Hovd", - "Asia/Jakarta", - "Asia/Krasnoyarsk", - "Asia/Novokuznetsk", - "Asia/Phnom_Penh", - "Asia/Pontianak", - "Asia/Saigon", - "Asia/Vientiane", - "Etc/GMT-7", - "Indian/Christmas", - "Antarctica/Casey", - "Asia/Brunei", - "Asia/Chita", - "Asia/Choibalsan", - "Asia/Chongqing", - "Asia/Chungking", - "Asia/Harbin", - "Asia/Hong_Kong", - "Asia/Irkutsk", - "Asia/Kuala_Lumpur", - "Asia/Kuching", - "Asia/Macao", - "Asia/Macau", - "Asia/Makassar", - "Asia/Manila", - "Asia/Shanghai", - "Asia/Singapore", - "Asia/Taipei", - "Asia/Ujung_Pandang", - "Asia/Ulaanbaatar", - "Asia/Ulan_Bator", - "Australia/Perth", - "Australia/West", - "Etc/GMT-8", - "Hongkong", - "PRC", - "ROC", - "Singapore", - "Australia/Eucla", - "Asia/Dili", - "Asia/Jayapura", - "Asia/Khandyga", - "Asia/Pyongyang", - "Asia/Seoul", - "Asia/Tokyo", - "Asia/Yakutsk", - "Etc/GMT-9", - "Japan", - "Pacific/Palau", - "ROK", - "Australia/Adelaide ", - "Australia/Broken_Hill", - "Australia/Darwin", - "Australia/North", - "Australia/South", - "Australia/Yancowinna ", - "Antarctica/DumontDUrville", - "Asia/Magadan", - "Asia/Sakhalin", - "Asia/Ust-Nera", - "Asia/Vladivostok", - "Australia/ACT", - "Australia/Brisbane", - "Australia/Canberra", - "Australia/Currie", - "Australia/Hobart", - "Australia/Lindeman", - "Australia/Melbourne", - "Australia/NSW", - "Australia/Queensland", - "Australia/Sydney", - "Australia/Tasmania", - "Australia/Victoria", - "Etc/GMT-10", - "Pacific/Chuuk", - "Pacific/Guam", - "Pacific/Port_Moresby", - "Pacific/Saipan", - "Pacific/Truk", - "Pacific/Yap", - "Australia/LHI", - "Australia/Lord_Howe", - "Antarctica/Macquarie", - "Asia/Srednekolymsk", - "Etc/GMT-11", - "Pacific/Bougainville", - "Pacific/Efate", - "Pacific/Guadalcanal", - "Pacific/Kosrae", - "Pacific/Noumea", - "Pacific/Pohnpei", - "Pacific/Ponape", - "Pacific/Norfolk", - "Antarctica/McMurdo", - "Antarctica/South_Pole", - "Asia/Anadyr", - "Asia/Kamchatka", - "Etc/GMT-12", - "Kwajalein", - "NZ", - "Pacific/Auckland", - "Pacific/Fiji", - "Pacific/Funafuti", - "Pacific/Kwajalein", - "Pacific/Majuro", - "Pacific/Nauru", - "Pacific/Tarawa", - "Pacific/Wake", - "Pacific/Wallis", - "NZ-CHAT", - "Pacific/Chatham", - "Etc/GMT-13", - "Pacific/Apia", - "Pacific/Enderbury", - "Pacific/Fakaofo", - "Pacific/Tongatapu", - "Etc/GMT-14", - "Pacific/Kiritimati" - ] - }, - "recurring_schedule": { - "$id": "#/properties/schedules/properties/recurring_schedule", - "type": "array", - "title": "The Recurring_schedule Schema", - "items": { - "$id": "#/properties/schedules/properties/recurring_schedule/items", - "type": "object", - "title": "The Recurring_schedule Items Schema", - "required": [ - "start_time", - "end_time", - "instance_min_count", - "instance_max_count" - ], - "oneOf": [ - { - "required": [ - "days_of_week" - ] - }, - { - "required": [ - "days_of_month" - ] - } - ], - "properties": { - "start_time": { - "$id": "#/properties/schedules/properties/recurring_schedule/items/properties/start_time", - "type": "string", - "title": "The Start_time Schema", - "pattern": "^(2[0-3]|1[0-9]|0[0-9]):([0-5][0-9])$" - }, - "end_time": { - "$id": "#/properties/schedules/properties/recurring_schedule/items/properties/end_time", - "type": "string", - "title": "The End_time Schema", - "pattern": "^(2[0-3]|1[0-9]|0[0-9]):([0-5][0-9])$" - }, - "days_of_week": { - "$id": "#/properties/schedules/properties/recurring_schedule/items/properties/days_of_week", - "type": "array", - "title": "The Days_of_week Schema", - "items": { - "$id": "#/properties/schedules/properties/recurring_schedule/items/properties/days_of_week/items", - "type": "integer", - "enum": [ - 1, - 2, - 3, - 4, - 5, - 6, - 7 - ] - } - }, - "days_of_month": { - "$id": "#/properties/schedules/properties/recurring_schedule/items/properties/days_of_month", - "type": "array", - "title": "The Days_of_month Schema", - "items": { - "$id": "#/properties/schedules/properties/recurring_schedule/items/properties/days_of_month/items", - "type": "integer", - "enum": [ - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20, - 21, - 22, - 23, - 24, - 25, - 26, - 27, - 28, - 29, - 30, - 31 - ] - } - }, - "instance_min_count": { - "$id": "#/properties/schedules/properties/recurring_schedule/items/properties/instance_min_count", - "type": "integer", - "title": "The Instance_min_count Schema" - }, - "instance_max_count": { - "$id": "#/properties/schedules/properties/recurring_schedule/items/properties/instance_max_count", - "type": "integer", - "title": "The Instance_max_count Schema" - }, - "initial_min_instance_count": { - "$id": "#/properties/schedules/properties/recurring_schedule/items/properties/initial_min_instance_count", - "type": "integer", - "title": "The Initial_min_instance_count Schema" - }, - "start_date": { - "oneOf": [ - { - "pattern": "^2[0-9]{3}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$", - "type": "string" - }, - { - "enum": [ - "" - ], - "type": "string" - } - ], - "description": "Start date of the recurrence in YYYY-MM-DD format" - }, - "end_date": { - "oneOf": [ - { - "pattern": "^2[0-9]{3}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$", - "type": "string" - }, - { - "enum": [ - "" - ], - "type": "string" - } - ], - "description": "End date of the recurrence in YYYY-MM-DD format" - } - } - } - }, - "specific_date": { - "$id": "#/properties/schedules/properties/specific_date", - "type": "array", - "title": "The Specific_date Schema", - "items": { - "$id": "#/properties/schedules/properties/specific_date/items", - "type": "object", - "title": "The Items Schema", - "required": [ - "start_date_time", - "end_date_time", - "instance_min_count", - "instance_max_count" - ], - "properties": { - "start_date_time": { - "$id": "#/properties/schedules/properties/specific_date/items/properties/start_date_time", - "type": "string", - "title": "The Start_date_time Schema", - "pattern": "^2[0-9]{3}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])T(2[0-3]|1[0-9]|0[0-9]):([0-5][0-9])$" - }, - "end_date_time": { - "$id": "#/properties/schedules/properties/specific_date/items/properties/end_date_time", - "type": "string", - "title": "The End_date_time Schema", - "default": "", - "pattern": "^2[0-9]{3}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])T(2[0-3]|1[0-9]|0[0-9]):([0-5][0-9])$" - }, - "instance_min_count": { - "$id": "#/properties/schedules/properties/specific_date/items/properties/instance_min_count", - "type": "integer", - "title": "The Instance_min_count Schema" - }, - "instance_max_count": { - "$id": "#/properties/schedules/properties/specific_date/items/properties/instance_max_count", - "type": "integer", - "title": "The Instance_max_count Schema" - }, - "initial_min_instance_count": { - "$id": "#/properties/schedules/properties/specific_date/items/properties/initial_min_instance_count", - "type": "integer", - "title": "The Initial_min_instance_count Schema" - } - } - } - } - } - } - }, - - "required": [ - "instance_min_count", - "instance_max_count" - ], - "anyOf": [ - { - "required": [ - "scaling_rules" - ] - }, - { - "required": [ - "schedules" - ] - } - ], - "additionalProperties": false -} diff --git a/src/autoscaler/api/binding_request/app-scaling-configuration.schema.json b/src/autoscaler/api/binding_request/app-scaling-configuration.schema.json deleted file mode 120000 index bd4df4ede2..0000000000 --- a/src/autoscaler/api/binding_request/app-scaling-configuration.schema.json +++ /dev/null @@ -1 +0,0 @@ -../../../../schema/json/app-scaling-configuration.schema.json \ No newline at end of file diff --git a/src/autoscaler/api/binding_request/binding-configuration.schema.json b/src/autoscaler/api/binding_request/binding-configuration.schema.json deleted file mode 120000 index 4c8af3a4bb..0000000000 --- a/src/autoscaler/api/binding_request/binding-configuration.schema.json +++ /dev/null @@ -1 +0,0 @@ -../../../../schema/json/binding-configuration.schema.json \ No newline at end of file diff --git a/src/autoscaler/api/binding_request/binding-request-parser.go b/src/autoscaler/api/binding_request/binding-request-parser.go deleted file mode 100644 index b14b578f66..0000000000 --- a/src/autoscaler/api/binding_request/binding-request-parser.go +++ /dev/null @@ -1,32 +0,0 @@ -package binding_request - -import ( - "fmt" - - "github.com/xeipuuv/gojsonschema" - - "code.cloudfoundry.org/app-autoscaler/src/autoscaler/models" -) - -type Parameters struct { - // 🚧 To-do: We should distinguish between raw data and correctly validated data. - Configuration *models.BindingConfig - - // 🚧 To-do: We should distinguish between raw data and correctly validated data. - ScalingPolicy *models.ScalingPolicy -} - -type JsonSchemaError []gojsonschema.ResultError - -func (e JsonSchemaError) Error() string { - var errors []gojsonschema.ResultError = e - return fmt.Sprintf("%s", errors) -} - -type Parser interface { - // Default policies are specified on service-instance-level. Consequently, we need to leave the - // field Parameters.ScalingPolicy empty when no policy has been specified and instead … let the - // consumer of the BindingRequest decided what to do with this (i.e. he will use then the - // default-policy.) - Parse(bindingReqParams string) (Parameters, error) -} diff --git a/src/autoscaler/api/binding_request/binding-request-parser_suite_test.go b/src/autoscaler/api/binding_request/binding-request-parser_suite_test.go deleted file mode 100644 index 8a9ee60158..0000000000 --- a/src/autoscaler/api/binding_request/binding-request-parser_suite_test.go +++ /dev/null @@ -1,13 +0,0 @@ -package binding_request_test - -import ( - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - - "testing" -) - -func TestServer(t *testing.T) { - RegisterFailHandler(Fail) - RunSpecs(t, "BindingRequestParser test suite") -} diff --git a/src/autoscaler/api/binding_request/binding-request-parser_test.go b/src/autoscaler/api/binding_request/binding-request-parser_test.go deleted file mode 100644 index f2f35cfb1d..0000000000 --- a/src/autoscaler/api/binding_request/binding-request-parser_test.go +++ /dev/null @@ -1,172 +0,0 @@ -package binding_request_test - -import ( - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - - br "code.cloudfoundry.org/app-autoscaler/src/autoscaler/api/binding_request" - clp "code.cloudfoundry.org/app-autoscaler/src/autoscaler/api/binding_request/clean_parser" - cp "code.cloudfoundry.org/app-autoscaler/src/autoscaler/api/binding_request/combined_parser" - lp "code.cloudfoundry.org/app-autoscaler/src/autoscaler/api/binding_request/legacy_parser" - "code.cloudfoundry.org/app-autoscaler/src/autoscaler/models" -) - -var _ = Describe("BindingRequestParsers", func() { - const cleanSchemaFilePath string = "file://./binding-request.json" - const validModernBindingRequestRaw string = ` - { - "configuration": { - "app_guid": "8d0cee08-23ad-4813-a779-ad8118ea0b91", - "custom_metrics": { - "metric_submission_strategy": { - "allow_from": "bound_app" - } - } - }, - "scaling-policy": { - "instance_min_count": 1, - "instance_max_count": 4, - "scaling_rules": [ - { - "metric_type": "memoryutil", - "breach_duration_secs": 600, - "threshold": 30, - "operator": "<", - "cool_down_secs": 300, - "adjustment": "-1" - }, - { - "metric_type": "memoryutil", - "breach_duration_secs": 600, - "threshold": 90, - "operator": ">=", - "cool_down_secs": 300, - "adjustment": "+1" - } - ] - } - }` - const validLegacyBindingRequestRaw string = ` - { - "configuration": { - "app_guid": "8d0cee08-23ad-4813-a779-ad8118ea0b91", - "custom_metrics": { - "metric_submission_strategy": { - "allow_from": "bound_app" - } - } - }, - "instance_min_count": 1, - "instance_max_count": 4, - "scaling_rules": [ - { - "metric_type": "memoryutil", - "breach_duration_secs": 600, - "threshold": 30, - "operator": "<", - "cool_down_secs": 300, - "adjustment": "-1" - }, - { - "metric_type": "memoryutil", - "breach_duration_secs": 600, - "threshold": 90, - "operator": ">=", - "cool_down_secs": 300, - "adjustment": "+1" - } - ] - }` - - Describe("CleanBindingRequestParser", func() { - var ( - cleanParser clp.CleanBindingRequestParser - err error - ) - var _ = BeforeEach(func() { - cleanParser, err = clp.NewFromFile(cleanSchemaFilePath) - Expect(err).NotTo(HaveOccurred()) - }) - Context("When using the new format for binding-requests", func() { - Context("and parsing a valid and complete one", func() { - It("should return a correctly populated BindingRequestParameters", func() { - bindingRequestRaw := validModernBindingRequestRaw - - bindingRequest, err := cleanParser.Parse(bindingRequestRaw) - - Expect(err).NotTo(HaveOccurred()) - Expect(bindingRequest.Configuration.AppGUID).To( - Equal(models.GUID("8d0cee08-23ad-4813-a779-ad8118ea0b91"))) - }) - }) - }) - }) - - Describe("LegacyBindingRequestParser", func() { - var ( - legacyParser lp.LegacyBindingRequestParser - err error - ) - var _ = BeforeEach(func() { - legacyParser, err = lp.New() - Expect(err).NotTo(HaveOccurred()) - }) - - Context("When using the legacy format for binding-requests", func() { - It("should return a correctly populated BindingRequestParameters", func() { - bindingRequestRaw := validLegacyBindingRequestRaw - - bindingRequest, err := legacyParser.Parse(bindingRequestRaw) - - Expect(err).NotTo(HaveOccurred()) - Expect(bindingRequest.Configuration.AppGUID). - To(Equal(models.GUID("8d0cee08-23ad-4813-a779-ad8118ea0b91"))) - // 🚧 To-do: Add a few more field-comparisons; - }) - }) - }) - - Describe("CombinedBindingRequestParser", func() { - var ( - cleanParser clp.CleanBindingRequestParser - legacyParser lp.LegacyBindingRequestParser - combinedParser cp.CombinedBindingRequestParser - - err error - ) - var _ = BeforeEach(func() { - cleanParser, err = clp.NewFromFile(cleanSchemaFilePath) - Expect(err).NotTo(HaveOccurred()) - legacyParser, err = lp.New() - Expect(err).NotTo(HaveOccurred()) - combinedParser = cp.New([]br.Parser{cleanParser, legacyParser}) - }) - - Context("When using the new format for binding-requests", func() { - Context("and parsing a valid and complete one", func() { - It("should return a correctly populated BindingRequestParameters", func() { - bindingRequestRaw := validModernBindingRequestRaw - - bindingRequest, err := combinedParser.Parse(bindingRequestRaw) - - Expect(err).NotTo(HaveOccurred()) - Expect(bindingRequest.Configuration.AppGUID).To( - Equal(models.GUID("8d0cee08-23ad-4813-a779-ad8118ea0b91"))) - }) - }) - }) - - Context("When using the legacy format for binding-requests", func() { - It("should return a correctly populated BindingRequestParameters", func() { - bindingRequestRaw := validLegacyBindingRequestRaw - - bindingRequest, err := combinedParser.Parse(bindingRequestRaw) - - Expect(err).NotTo(HaveOccurred()) - Expect(bindingRequest.Configuration.AppGUID). - To(Equal(models.GUID("8d0cee08-23ad-4813-a779-ad8118ea0b91"))) - // 🚧 To-do: Add a few more field-comparisons; - }) - }) - }) -}) diff --git a/src/autoscaler/api/binding_request/clean_parser/json-structure.go b/src/autoscaler/api/binding_request/clean_parser/json-structure.go deleted file mode 100644 index 519799b480..0000000000 --- a/src/autoscaler/api/binding_request/clean_parser/json-structure.go +++ /dev/null @@ -1,70 +0,0 @@ -package clean_parser - -type parameters struct { - Configuration *bindingCfg `json:"configuration"` - ScalingPolicy *scalingPolicy `json:"scaling-policy"` -} - -// ================================================================================ -// Binding-configuration -// ================================================================================ - -type bindingCfg struct { - CustomMetricsCfg customMetricsCfg - AppGuid string `json:"app_guid"` -} - -type customMetricsCfg struct { - MetricSubmStrat metricSubmStrat `json:"metric_submission_strategy"` -} - -type metricSubmStrat struct { - AllowFrom string `json:"allow_from"` -} - -// ================================================================================ -// Scaling-policy -// ================================================================================ - -type scalingPolicy struct { - SchemaVersion string `json:"schema-version"` - InstanceMinCount int `json:"instance_min_count"` - InstanceMaxCount int `json:"instance_max_count"` - ScalingRules []scalingRule `json:"scaling_rules,omitempty"` - Schedules *scalingSchedule `json:"schedules,omitempty"` -} - -type scalingRule struct { - MetricType string `json:"metric_type"` - BreachDurationSecs int `json:"breach_duration_secs,omitempty"` - Threshold int64 `json:"threshold"` - Operator string `json:"operator"` - CoolDownSecs int `json:"cool_down_secs,omitempty"` - Adjustment string `json:"adjustment"` -} - -type scalingSchedule struct { - Timezone string `json:"timezone"` - RecurringSchedule []recurringSchedule `json:"recurring_schedule,omitempty"` - SpecificDate []specificDate `json:"specific_date,omitempty"` -} - -type recurringSchedule struct { - StartTime string `json:"start_time"` - EndTime string `json:"end_time"` - DaysOfWeek []int `json:"days_of_week,omitempty"` - DaysOfMonth []int `json:"days_of_month,omitempty"` - InstanceMinCount int `json:"instance_min_count"` - InstanceMaxCount int `json:"instance_max_count"` - InitialMinInstanceCount int `json:"initial_min_instance_count,omitempty"` - StartDate string `json:"start_date,omitempty"` - EndDate string `json:"end_date,omitempty"` -} - -type specificDate struct { - StartDateTime string `json:"start_date_time"` - EndDateTime string `json:"end_date_time"` - InstanceMinCount int `json:"instance_min_count"` - InstanceMaxCount int `json:"instance_max_count"` - InitialMinInstanceCount int `json:"initial_min_instance_count,omitempty"` -} diff --git a/src/autoscaler/api/binding_request/clean_parser/parser.go b/src/autoscaler/api/binding_request/clean_parser/parser.go deleted file mode 100644 index 5a5c711105..0000000000 --- a/src/autoscaler/api/binding_request/clean_parser/parser.go +++ /dev/null @@ -1,128 +0,0 @@ -package clean_parser - -import ( - "encoding/json" - - "github.com/xeipuuv/gojsonschema" - - "code.cloudfoundry.org/app-autoscaler/src/autoscaler/api/binding_request" - "code.cloudfoundry.org/app-autoscaler/src/autoscaler/models" -) - -type CleanBindingRequestParser struct { - schema *gojsonschema.Schema -} - -var _ binding_request.Parser = CleanBindingRequestParser{} - -func new(jsonLoader gojsonschema.JSONLoader) (CleanBindingRequestParser, error) { - schema, err := gojsonschema.NewSchema(jsonLoader) - if err != nil { - return CleanBindingRequestParser{}, err - } else { - return CleanBindingRequestParser{schema: schema}, nil - } -} - -func NewFromString(jsonSchema string) (CleanBindingRequestParser, error) { - schemaLoader := gojsonschema.NewStringLoader(jsonSchema) - return new(schemaLoader) -} - -func NewFromFile(pathToSchemaFile string) (CleanBindingRequestParser, error) { - // The type for parameter `pathToSchemaFile` is same type as used in golang's std-library - schemaLoader := gojsonschema.NewReferenceLoader(pathToSchemaFile) - return new(schemaLoader) -} - -func (p CleanBindingRequestParser) Parse(bindingReqParams string) (binding_request.Parameters, error) { - documentLoader := gojsonschema.NewStringLoader(bindingReqParams) - validationResult, err := p.schema.Validate(documentLoader) - if err != nil { - // Defined by the implementation of `Validate`, this only happens, if the provided document - // (in this context `documentLoader`) can not be loaded. - return binding_request.Parameters{}, err - } else if !validationResult.Valid() { - // The error contains a description of all detected violations against the schema. - allErrors := binding_request.JsonSchemaError(validationResult.Errors()) - return binding_request.Parameters{}, allErrors - } - - var parsedParameters parameters - err = json.Unmarshal([]byte(bindingReqParams), &parsedParameters) - if err != nil { - return binding_request.Parameters{}, err - } - - return toBindingParameters(parsedParameters), nil -} - -func toBindingParameters(params parameters) binding_request.Parameters { - result := binding_request.Parameters{} - if params.Configuration != nil { - result.Configuration = &models.BindingConfig{} - - result.Configuration.AppGUID = models.GUID(params.Configuration.AppGuid) - result.Configuration.SetCustomMetricsStrategy(params.Configuration.CustomMetricsCfg.MetricSubmStrat.AllowFrom) - } - - if params.ScalingPolicy != nil { - result.ScalingPolicy = &models.ScalingPolicy{} - - result.ScalingPolicy.InstanceMax = params.ScalingPolicy.InstanceMaxCount - result.ScalingPolicy.InstanceMin = params.ScalingPolicy.InstanceMinCount - - result.ScalingPolicy.ScalingRules = []*models.ScalingRule{} - for _, rule := range params.ScalingPolicy.ScalingRules { - r := models.ScalingRule{ - MetricType: rule.MetricType, - BreachDurationSeconds: rule.BreachDurationSecs, - Threshold: rule.Threshold, - Operator: rule.Operator, - CoolDownSeconds: rule.CoolDownSecs, - Adjustment: rule.Adjustment, - } - result.ScalingPolicy.ScalingRules = append(result.ScalingPolicy.ScalingRules, &r) - } - - if params.ScalingPolicy.Schedules != nil { - result.ScalingPolicy.Schedules = &models.ScalingSchedules{ - Timezone: params.ScalingPolicy.Schedules.Timezone, - } - - if params.ScalingPolicy.Schedules.RecurringSchedule != nil { - result.ScalingPolicy.Schedules.RecurringSchedules = []*models.RecurringSchedule{} - for _, schedule := range params.ScalingPolicy.Schedules.RecurringSchedule { - rs := models.RecurringSchedule{ - StartTime: schedule.StartTime, - EndTime: schedule.EndTime, - DaysOfWeek: schedule.DaysOfWeek, - DaysOfMonth: schedule.DaysOfMonth, - ScheduledInstanceMin: schedule.InstanceMinCount, - ScheduledInstanceMax: schedule.InstanceMaxCount, - ScheduledInstanceInit: schedule.InitialMinInstanceCount, - StartDate: schedule.StartDate, - EndDate: schedule.EndDate, - } - result.ScalingPolicy.Schedules.RecurringSchedules = append(result.ScalingPolicy.Schedules.RecurringSchedules, &rs) - } - } - - if params.ScalingPolicy.Schedules.SpecificDate != nil { - result.ScalingPolicy.Schedules.SpecificDateSchedules = []*models.SpecificDateSchedule{} - for _, specificDate := range params.ScalingPolicy.Schedules.SpecificDate { - sd := models.SpecificDateSchedule{ - StartDateTime: specificDate.StartDateTime, - EndDateTime: specificDate.EndDateTime, - ScheduledInstanceMin: specificDate.InstanceMinCount, - ScheduledInstanceMax: specificDate.InstanceMaxCount, - ScheduledInstanceInit: specificDate.InitialMinInstanceCount, - } - result.ScalingPolicy.Schedules.SpecificDateSchedules = append(result.ScalingPolicy.Schedules.SpecificDateSchedules, &sd) - } - } - } - } - - return result -} diff --git a/src/autoscaler/api/binding_request/combined_parser/parser.go b/src/autoscaler/api/binding_request/combined_parser/parser.go deleted file mode 100644 index 96e23082c0..0000000000 --- a/src/autoscaler/api/binding_request/combined_parser/parser.go +++ /dev/null @@ -1,35 +0,0 @@ -package combined_parser - -import ( - "code.cloudfoundry.org/app-autoscaler/src/autoscaler/api/binding_request" -) - -// Combined parser that tries out all other parser that are associated to it in order -// and returns the first successful result. -// -// In case all associated parser fail, it returns the error of the first one. -type CombinedBindingRequestParser struct { - parsers []binding_request.Parser -} - -// Ensure CombinedBindingRequestParser implements the binding_request.Parser interface. -var _ binding_request.Parser = CombinedBindingRequestParser{} - -func New(parsers []binding_request.Parser) CombinedBindingRequestParser { - return CombinedBindingRequestParser{parsers: parsers} -} - -func (p CombinedBindingRequestParser) Parse( - bindingReqParams string, -) (binding_request.Parameters, error) { - var firstErr error - for i, parser := range p.parsers { - params, err := parser.Parse(bindingReqParams) - if i == 0 && err != nil { - firstErr = err // Store the first error to return later if no parser is successful. - } else if err == nil { - return params, nil - } - } - return binding_request.Parameters{}, firstErr -} diff --git a/src/autoscaler/api/binding_request/legacy_parser/json-structure.go b/src/autoscaler/api/binding_request/legacy_parser/json-structure.go deleted file mode 100644 index 1b9b3c5410..0000000000 --- a/src/autoscaler/api/binding_request/legacy_parser/json-structure.go +++ /dev/null @@ -1,67 +0,0 @@ -package legacy_parser - -import "code.cloudfoundry.org/app-autoscaler/src/autoscaler/models" - -type policyAndBindingCfg struct { - BindingConfig bindingConfig `json:"configuration"` - InstanceMin int `json:"instance_min_count"` - InstanceMax int `json:"instance_max_count"` - ScalingRules []*scalingRule `json:"scaling_rules,omitempty"` - Schedules *scalingSchedules `json:"schedules,omitempty"` -} - -// ================================================================================ -// Binding-configuration -// ================================================================================ - -type bindingConfig struct { - AppGUID models.GUID `json:"app_guid,omitempty"` // Empty value represents null-value (i.e. not set). - CustomMetrics customMetricsConfig `json:"custom_metrics,omitempty"` -} - -type customMetricsConfig struct { - MetricSubmissionStrategy metricsSubmissionStrategy `json:"metric_submission_strategy"` -} - -type metricsSubmissionStrategy struct { - AllowFrom string `json:"allow_from"` -} - -// ================================================================================ -// Scaling-policy details -// ================================================================================ - -type scalingRule struct { - MetricType string `json:"metric_type"` - BreachDurationSeconds int `json:"breach_duration_secs,omitempty"` - Threshold int64 `json:"threshold"` - Operator string `json:"operator"` - CoolDownSeconds int `json:"cool_down_secs,omitempty"` - Adjustment string `json:"adjustment"` -} - -type scalingSchedules struct { - Timezone string `json:"timezone"` - RecurringSchedules []*recurringSchedule `json:"recurring_schedule,omitempty"` - SpecificDateSchedules []*specificDateSchedule `json:"specific_date,omitempty"` -} - -type recurringSchedule struct { - StartTime string `json:"start_time"` - EndTime string `json:"end_time"` - DaysOfWeek []int `json:"days_of_week,omitempty"` - DaysOfMonth []int `json:"days_of_month,omitempty"` - StartDate string `json:"start_date,omitempty"` - EndDate string `json:"end_date,omitempty"` - ScheduledInstanceMin int `json:"instance_min_count"` - ScheduledInstanceMax int `json:"instance_max_count"` - ScheduledInstanceInit int `json:"initial_min_instance_count,omitempty"` -} - -type specificDateSchedule struct { - StartDateTime string `json:"start_date_time"` - EndDateTime string `json:"end_date_time"` - ScheduledInstanceMin int `json:"instance_min_count"` - ScheduledInstanceMax int `json:"instance_max_count"` - ScheduledInstanceInit int `json:"initial_min_instance_count,omitempty"` -} diff --git a/src/autoscaler/api/binding_request/legacy_parser/parser.go b/src/autoscaler/api/binding_request/legacy_parser/parser.go deleted file mode 100644 index 0081304d3b..0000000000 --- a/src/autoscaler/api/binding_request/legacy_parser/parser.go +++ /dev/null @@ -1,111 +0,0 @@ -package legacy_parser - -import ( - "encoding/json" - - "github.com/xeipuuv/gojsonschema" - - "code.cloudfoundry.org/app-autoscaler/src/autoscaler/api/binding_request" - "code.cloudfoundry.org/app-autoscaler/src/autoscaler/models" -) - -type LegacyBindingRequestParser struct { - schema *gojsonschema.Schema -} - -var _ binding_request.Parser = LegacyBindingRequestParser{} - -func New() (LegacyBindingRequestParser, error) { - const schemaFilePath string = "file://./legacy-binding-request.json" - schemaLoader := gojsonschema.NewReferenceLoader(schemaFilePath) - schema, err := gojsonschema.NewSchema(schemaLoader) - if err != nil { - return LegacyBindingRequestParser{}, err - } - return LegacyBindingRequestParser{schema: schema}, nil -} - -func (p LegacyBindingRequestParser) Parse(bindingReqParams string) (binding_request.Parameters, error) { - documentLoader := gojsonschema.NewStringLoader(bindingReqParams) - validationResult, err := p.schema.Validate(documentLoader) - if err != nil { - // Defined by the implementation of `Validate`, this only happens, if the provided document - // (in this context `documentLoader`) can not be loaded. - return binding_request.Parameters{}, err - } else if !validationResult.Valid() { - // The error contains a description of all detected violations against the schema. - allErrors := binding_request.JsonSchemaError(validationResult.Errors()) - return binding_request.Parameters{}, allErrors - } - - var parsedParameters policyAndBindingCfg - err = json.Unmarshal([]byte(bindingReqParams), &parsedParameters) - if err != nil { - return binding_request.Parameters{}, err - } - - return toBindingParameters(parsedParameters), nil -} - -func toBindingParameters(params policyAndBindingCfg) binding_request.Parameters { - result := binding_request.Parameters{} - result.Configuration = &models.BindingConfig{ - AppGUID: models.GUID(params.BindingConfig.AppGUID), - CustomMetrics: &models.CustomMetricsConfig{ - MetricSubmissionStrategy: models.MetricsSubmissionStrategy{ - AllowFrom: params.BindingConfig.CustomMetrics.MetricSubmissionStrategy.AllowFrom, - }, - }, - } - - result.ScalingPolicy = &models.ScalingPolicy{ - InstanceMin: params.InstanceMin, - InstanceMax: params.InstanceMax, - } - - for _, rule := range params.ScalingRules { - scalingRule := &models.ScalingRule{ - MetricType: rule.MetricType, - BreachDurationSeconds: rule.BreachDurationSeconds, - Threshold: rule.Threshold, - Operator: rule.Operator, - CoolDownSeconds: rule.CoolDownSeconds, - Adjustment: rule.Adjustment, - } - result.ScalingPolicy.ScalingRules = append(result.ScalingPolicy.ScalingRules, scalingRule) - } - - if params.Schedules != nil { - result.ScalingPolicy.Schedules = &models.ScalingSchedules{ - Timezone: params.Schedules.Timezone, - } - - for _, recurring := range params.Schedules.RecurringSchedules { - recurringSchedule := &models.RecurringSchedule{ - StartTime: recurring.StartTime, - EndTime: recurring.EndTime, - DaysOfWeek: recurring.DaysOfWeek, - DaysOfMonth: recurring.DaysOfMonth, - StartDate: recurring.StartDate, - EndDate: recurring.EndDate, - ScheduledInstanceMin: recurring.ScheduledInstanceMin, - ScheduledInstanceMax: recurring.ScheduledInstanceMax, - ScheduledInstanceInit: recurring.ScheduledInstanceInit, - } - result.ScalingPolicy.Schedules.RecurringSchedules = append(result.ScalingPolicy.Schedules.RecurringSchedules, recurringSchedule) - } - - for _, specific := range params.Schedules.SpecificDateSchedules { - specificDateSchedule := &models.SpecificDateSchedule{ - StartDateTime: specific.StartDateTime, - EndDateTime: specific.EndDateTime, - ScheduledInstanceMin: specific.ScheduledInstanceMin, - ScheduledInstanceMax: specific.ScheduledInstanceMax, - ScheduledInstanceInit: specific.ScheduledInstanceInit, - } - result.ScalingPolicy.Schedules.SpecificDateSchedules = append(result.ScalingPolicy.Schedules.SpecificDateSchedules, specificDateSchedule) - } - } - - return result -} diff --git a/src/autoscaler/api/binding_request/policy-configuration.legacy-schema.json b/src/autoscaler/api/binding_request/policy-configuration.legacy-schema.json deleted file mode 120000 index c754806e59..0000000000 --- a/src/autoscaler/api/binding_request/policy-configuration.legacy-schema.json +++ /dev/null @@ -1 +0,0 @@ -../../../../schema/json/policy-configuration.legacy-schema.json \ No newline at end of file diff --git a/src/autoscaler/api/binding_request/policy-configuration.schema.json b/src/autoscaler/api/binding_request/policy-configuration.schema.json deleted file mode 120000 index 48ce660b34..0000000000 --- a/src/autoscaler/api/binding_request/policy-configuration.schema.json +++ /dev/null @@ -1 +0,0 @@ -../../../../schema/json/policy-configuration.schema.json \ No newline at end of file diff --git a/src/autoscaler/api/binding_request/scaling-policy.legacy-schema.json b/src/autoscaler/api/binding_request/scaling-policy.legacy-schema.json deleted file mode 120000 index 98ca85b397..0000000000 --- a/src/autoscaler/api/binding_request/scaling-policy.legacy-schema.json +++ /dev/null @@ -1 +0,0 @@ -../../../../schema/json/scaling-policy.legacy-schema.json \ No newline at end of file diff --git a/src/autoscaler/api/binding_request/scaling-policy.schema.json b/src/autoscaler/api/binding_request/scaling-policy.schema.json deleted file mode 120000 index e50dc96b9d..0000000000 --- a/src/autoscaler/api/binding_request/scaling-policy.schema.json +++ /dev/null @@ -1 +0,0 @@ -../../../../schema/json/scaling-policy.schema.json \ No newline at end of file diff --git a/src/autoscaler/api/binding_request/shared_definitions.json b/src/autoscaler/api/binding_request/shared_definitions.json deleted file mode 120000 index e1fc4df59e..0000000000 --- a/src/autoscaler/api/binding_request/shared_definitions.json +++ /dev/null @@ -1 +0,0 @@ -../../../../schema/json/shared_definitions.json \ No newline at end of file From 17c0ca4f8fcc7418212589f2883bf1752c43ed34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Weisbarth?= Date: Wed, 8 Oct 2025 14:51:29 +0200 Subject: [PATCH 06/20] Remove leftovers from old schema-file: Test-fixing! --- packages/golangapiserver/packaging | 19 ++--- schema/api/policy-api.openapi.yaml | 2 +- .../policy-configuration.legacy-schema.json | 43 ++++------ schema/json/scaling-policy.legacy-schema.json | 7 ++ .../api/broker/broker_suite_test.go | 2 +- .../api/brokerserver/broker_handler_test.go | 7 +- .../brokerserver/broker_server_suite_test.go | 2 +- src/autoscaler/api/cmd/api/api_suite_test.go | 2 +- .../policy-configuration.legacy-schema.json | 1 + .../policyvalidator/policy_validator_test.go | 80 ++++++++++--------- .../scaling-policy.legacy-schema.json | 1 + .../policyvalidator/shared_definitions.json | 1 + .../public_api_handler_test.go | 29 ++++--- .../publicapiserver_suite_test.go | 2 +- src/autoscaler/integration/components_test.go | 2 +- 15 files changed, 100 insertions(+), 100 deletions(-) create mode 120000 src/autoscaler/api/policyvalidator/policy-configuration.legacy-schema.json create mode 120000 src/autoscaler/api/policyvalidator/scaling-policy.legacy-schema.json create mode 120000 src/autoscaler/api/policyvalidator/shared_definitions.json diff --git a/packages/golangapiserver/packaging b/packages/golangapiserver/packaging index 3437c4fc00..654bb4b777 100644 --- a/packages/golangapiserver/packaging +++ b/packages/golangapiserver/packaging @@ -1,20 +1,17 @@ set -e -x export GOROOT=$(readlink -nf /var/vcap/packages/golang-1-linux) -export PATH=$GOROOT/bin:$PATH -export GOPATH=${BOSH_COMPILE_TARGET} +export PATH="${GOROOT}/bin:${PATH}" +export GOPATH="${BOSH_COMPILE_TARGET}" export GOCACHE=/tmp/gocache -pushd ${BOSH_COMPILE_TARGET}/autoscaler +pushd "${BOSH_COMPILE_TARGET}/autoscaler" GOPROXY=off make build-api popd -cp -a ${BOSH_COMPILE_TARGET}/autoscaler/build/api ${BOSH_INSTALL_TARGET} -cp -a ${BOSH_COMPILE_TARGET}/autoscaler/api/db/api.db.changelog.yml ${BOSH_INSTALL_TARGET} -cp -a ${BOSH_COMPILE_TARGET}/autoscaler/api/db/servicebroker.db.changelog.yaml ${BOSH_INSTALL_TARGET} - -cp -a ${BOSH_COMPILE_TARGET}/autoscaler/api/policyvalidator/policy_json.schema.json ${BOSH_INSTALL_TARGET} -cp -a ${BOSH_COMPILE_TARGET}/autoscaler/api/schemas/catalog.schema.json ${BOSH_INSTALL_TARGET} - - +cp --archive "${BOSH_COMPILE_TARGET}/autoscaler/build/api" "${BOSH_INSTALL_TARGET}" +cp --archive "${BOSH_COMPILE_TARGET}/autoscaler/api/db/api.db.changelog.yml" "${BOSH_INSTALL_TARGET}" +cp --archive "${BOSH_COMPILE_TARGET}/autoscaler/api/db/servicebroker.db.changelog.yaml" "${BOSH_INSTALL_TARGET}" +cp --archive "${BOSH_COMPILE_TARGET}/autoscaler/api/policyvalidator/policy_json.schema.json" "${BOSH_INSTALL_TARGET}" +cp --archive "${BOSH_COMPILE_TARGET}/autoscaler/api/catalog.schema.json" "${BOSH_INSTALL_TARGET}" diff --git a/schema/api/policy-api.openapi.yaml b/schema/api/policy-api.openapi.yaml index c00dc18992..c15e858270 100644 --- a/schema/api/policy-api.openapi.yaml +++ b/schema/api/policy-api.openapi.yaml @@ -171,7 +171,7 @@ components: type: string example: Asia/Shanghai # TODO: Try to make use of - #- $ref: "../../src/autoscaler/api/policyvalidator/policy_json.schema.json#/" # TODO: + #- $ref: "../../src/autoscaler/schema/api/policyvalidator/policy_json.schema.json#/" # TODO: recurring_schedule: type: array items: diff --git a/schema/json/policy-configuration.legacy-schema.json b/schema/json/policy-configuration.legacy-schema.json index dda9ff9d92..ff06aec9b8 100644 --- a/schema/json/policy-configuration.legacy-schema.json +++ b/schema/json/policy-configuration.legacy-schema.json @@ -5,49 +5,36 @@ "type": "object", "properties": { - "configuration": { + "custom_metrics": { "type": "object", "properties": { - "custom_metrics": { + "metric_submission_strategy": { "type": "object", "properties": { - "metric_submission_strategy": { - "type": "object", - "properties": { - "allow_from": { - "type": "string", - "enum": [ - "bound_app", - "same_app" - ] - } - }, - "required": [ - "allow_from" + "allow_from": { + "type": "string", + "enum": [ + "bound_app", + "same_app" ] } }, "required": [ - "metric_submission_strategy" - ], - "additionalProperties": false - }, - "app_guid": { - "$ref": "./shared_definitions.json#/schemas/guid" - }, - "credential-type": { - "type": "string", - "enum": [ - "x509", - "binding-secret" + "allow_from" ] } }, "required": [ - "custom_metrics" + "metric_submission_strategy" ], "additionalProperties": false + }, + "app_guid": { + "$ref": "./shared_definitions.json#/schemas/guid" } }, + "required": [ + "custom_metrics" + ], "additionalProperties": false } diff --git a/schema/json/scaling-policy.legacy-schema.json b/schema/json/scaling-policy.legacy-schema.json index e3d2e8cc59..18b7485c43 100644 --- a/schema/json/scaling-policy.legacy-schema.json +++ b/schema/json/scaling-policy.legacy-schema.json @@ -10,6 +10,13 @@ "type": "string", "pattern": "^[0-9]+(\\.[0-9]+)?$" }, + "credential-type": { + "type": "string", + "enum": [ + "x509", + "binding-secret" + ] + }, "configuration": { "$ref": "./policy-configuration.legacy-schema.json" }, diff --git a/src/autoscaler/api/broker/broker_suite_test.go b/src/autoscaler/api/broker/broker_suite_test.go index 4e9442780c..bcd7df9a06 100644 --- a/src/autoscaler/api/broker/broker_suite_test.go +++ b/src/autoscaler/api/broker/broker_suite_test.go @@ -50,7 +50,7 @@ var _ = BeforeSuite(func() { conf = &config.Config{ CatalogPath: "../exampleconfig/catalog-example.json", DashboardRedirectURI: dashBoardURL, - PolicySchemaPath: "../policyvalidator/policy_json.schema.json", + PolicySchemaPath: "../policyvalidator/scaling-policy.legacy-schema.json", DefaultCustomMetricsCredentialType: "binding-secret", } diff --git a/src/autoscaler/api/brokerserver/broker_handler_test.go b/src/autoscaler/api/brokerserver/broker_handler_test.go index 07dc84fa04..e7fbed380b 100644 --- a/src/autoscaler/api/brokerserver/broker_handler_test.go +++ b/src/autoscaler/api/brokerserver/broker_handler_test.go @@ -934,7 +934,7 @@ var _ = Describe("BrokerHandler", func() { "configuration": { "custom_metrics": { "metric_submission_strategy": { - "allow_from": "same_app" + "allow_from": "different_app" } } }, @@ -995,7 +995,7 @@ var _ = Describe("BrokerHandler", func() { verifyScheduleIsUpdatedInScheduler(testAppId, bindingPolicy) }) It("should fail with 400", func() { - Expect(resp.Body.String()).To(ContainSubstring("{\"description\":\"invalid policy provided: [{\\\"context\\\":\\\"(root).configuration.custom_metrics.metric_submission_strategy.allow_from\\\",\\\"description\\\":\\\"configuration.custom_metrics.metric_submission_strategy.allow_from must be one of the following: \\\\\\\"bound_app\\\\\\\"\\\"}]\"}")) + Expect(resp.Body.String()).To(ContainSubstring("{\"description\":\"invalid policy provided: [{\\\"context\\\":\\\"(root).configuration.custom_metrics.metric_submission_strategy.allow_from\\\",\\\"description\\\":\\\"configuration.custom_metrics.metric_submission_strategy.allow_from must be one of the following: \\\\\\\"bound_app\\\\\\\", \\\\\\\"same_app\\\\\\\"\\\"}]\"}")) Expect(resp.Code).To(Equal(http.StatusBadRequest)) }) }) @@ -1196,8 +1196,9 @@ var _ = Describe("BrokerHandler", func() { }) It("fails with 400", func() { Expect(resp.Code).To(Equal(http.StatusBadRequest)) - Expect(resp.Body.String()).To(MatchJSON(`{"error": "validate-credential-type","description": "invalid credential type provided: allowed values are [binding-secret, x509]"}`)) + Expect(resp.Body.String()).To(MatchJSON(`{"description": "invalid policy provided: [{\"context\":\"(root).credential-type\",\"description\":\"credential-type must be one of the following: \\\"x509\\\", \\\"binding-secret\\\"\"}]"}`)) }) + }) Context("credential-type is set to binding-secret", func() { const testBindingPolicy = `{ diff --git a/src/autoscaler/api/brokerserver/broker_server_suite_test.go b/src/autoscaler/api/brokerserver/broker_server_suite_test.go index 538f494b41..7ac32f5c1c 100644 --- a/src/autoscaler/api/brokerserver/broker_server_suite_test.go +++ b/src/autoscaler/api/brokerserver/broker_server_suite_test.go @@ -129,7 +129,7 @@ var _ = BeforeSuite(func() { }, CatalogPath: "../exampleconfig/catalog-example.json", CatalogSchemaPath: "../schemas/catalog.schema.json", - PolicySchemaPath: "../policyvalidator/policy_json.schema.json", + PolicySchemaPath: "../policyvalidator/scaling-policy.legacy-schema.json", Scheduler: config.SchedulerConfig{ SchedulerURL: schedulerServer.URL(), }, diff --git a/src/autoscaler/api/cmd/api/api_suite_test.go b/src/autoscaler/api/cmd/api/api_suite_test.go index 636afdf54a..c9b2cd9bd5 100644 --- a/src/autoscaler/api/cmd/api/api_suite_test.go +++ b/src/autoscaler/api/cmd/api/api_suite_test.go @@ -164,7 +164,7 @@ var _ = SynchronizedBeforeSuite(func() []byte { conf.CatalogPath = "../../exampleconfig/catalog-example.json" conf.CatalogSchemaPath = "../../schemas/catalog.schema.json" - conf.PolicySchemaPath = "../../policyvalidator/policy_json.schema.json" + conf.PolicySchemaPath = "../policyvalidator/scaling-policy.legacy-schema.json" schedulerServer = ghttp.NewServer() conf.Scheduler.SchedulerURL = schedulerServer.URL() diff --git a/src/autoscaler/api/policyvalidator/policy-configuration.legacy-schema.json b/src/autoscaler/api/policyvalidator/policy-configuration.legacy-schema.json new file mode 120000 index 0000000000..c754806e59 --- /dev/null +++ b/src/autoscaler/api/policyvalidator/policy-configuration.legacy-schema.json @@ -0,0 +1 @@ +../../../../schema/json/policy-configuration.legacy-schema.json \ No newline at end of file diff --git a/src/autoscaler/api/policyvalidator/policy_validator_test.go b/src/autoscaler/api/policyvalidator/policy_validator_test.go index fac7eb36eb..249468f82a 100644 --- a/src/autoscaler/api/policyvalidator/policy_validator_test.go +++ b/src/autoscaler/api/policyvalidator/policy_validator_test.go @@ -48,7 +48,7 @@ var _ = Describe("PolicyValidator", func() { upperDiskThreshold = 2 * 1024 policyValidator = NewPolicyValidator( - "./policy_json.schema.json", + "./scaling-policy.legacy-schema.json", lowerCPUThreshold, upperCPUThreshold, lowerCPUUtilThreshold, @@ -108,6 +108,7 @@ var _ = Describe("PolicyValidator", func() { })) }) }) + Context("when instance_min_count is < 1", func() { BeforeEach(func() { policyString = `{ @@ -221,43 +222,44 @@ var _ = Describe("PolicyValidator", func() { }) }) - Context("when additional fields are present", func() { - BeforeEach(func() { - policyString = `{ - "instance_max_count":4, - "instance_min_count":1, - "scaling_rules":[ - { - "metric_type":"memoryutil", - "stats_window_secs": 600, - "breach_duration_secs":600, - "threshold":90, - "operator":">=", - "cool_down_secs":300, - "adjustment":"+1" - }], - "is_admin": true, - "is_sso": true, - "role": "admin" - }` - }) - It("the validation succeed and remove them", func() { - validPolicyString := `{ - "instance_max_count":4, - "instance_min_count":1, - "scaling_rules":[ - { - "metric_type":"memoryutil", - "breach_duration_secs":600, - "threshold":90, - "operator":">=", - "cool_down_secs":300, - "adjustment":"+1" - }] - }` - Expect(policyJson).To(MatchJSON(validPolicyString)) - }) - }) + // // 🚧🧐 To-do for the reviewer: Check if we can just ommit this test. + // Context("when additional fields are present", func() { + // BeforeEach(func() { + // policyString = `{ + // "instance_max_count":4, + // "instance_min_count":1, + // "scaling_rules":[ + // { + // "metric_type":"memoryutil", + // "stats_window_secs": 600, + // "breach_duration_secs":600, + // "threshold":90, + // "operator":">=", + // "cool_down_secs":300, + // "adjustment":"+1" + // }], + // "is_admin": true, + // "is_sso": true, + // "role": "admin" + // }` + // }) + // It("the validation succeed and remove them", func() { + // validPolicyString := `{ + // "instance_max_count":4, + // "instance_min_count":1, + // "scaling_rules":[ + // { + // "metric_type":"memoryutil", + // "breach_duration_secs":600, + // "threshold":90, + // "operator":">=", + // "cool_down_secs":300, + // "adjustment":"+1" + // }] + // }` + // Expect(policyJson).To(MatchJSON(validPolicyString)) + // }) + // }) Context("Scaling Rules", func() { @@ -2648,7 +2650,7 @@ var _ = Describe("PolicyValidator", func() { Expect(errResult).To(Equal([]PolicyValidationErrors{ { Context: "(root).configuration.custom_metrics.metric_submission_strategy.allow_from", - Description: "configuration.custom_metrics.metric_submission_strategy.allow_from must be one of the following: \"bound_app\"", + Description: "configuration.custom_metrics.metric_submission_strategy.allow_from must be one of the following: \"bound_app\", \"same_app\"", }, })) }) diff --git a/src/autoscaler/api/policyvalidator/scaling-policy.legacy-schema.json b/src/autoscaler/api/policyvalidator/scaling-policy.legacy-schema.json new file mode 120000 index 0000000000..98ca85b397 --- /dev/null +++ b/src/autoscaler/api/policyvalidator/scaling-policy.legacy-schema.json @@ -0,0 +1 @@ +../../../../schema/json/scaling-policy.legacy-schema.json \ No newline at end of file diff --git a/src/autoscaler/api/policyvalidator/shared_definitions.json b/src/autoscaler/api/policyvalidator/shared_definitions.json new file mode 120000 index 0000000000..e1fc4df59e --- /dev/null +++ b/src/autoscaler/api/policyvalidator/shared_definitions.json @@ -0,0 +1 @@ +../../../../schema/json/shared_definitions.json \ No newline at end of file diff --git a/src/autoscaler/api/publicapiserver/public_api_handler_test.go b/src/autoscaler/api/publicapiserver/public_api_handler_test.go index 9cb2c5214c..d12e82097e 100644 --- a/src/autoscaler/api/publicapiserver/public_api_handler_test.go +++ b/src/autoscaler/api/publicapiserver/public_api_handler_test.go @@ -99,7 +99,7 @@ var _ = Describe("PublicApiHandler", func() { "configuration": { "custom_metrics": { "metric_submission_strategy": { - "allow_from": "same_app" + "allow_from": "different_app" } } }, @@ -329,6 +329,7 @@ var _ = Describe("PublicApiHandler", func() { Expect(resp.Body.String()).To(Equal(`{"code":"Bad Request","message":"AppId is required"}`)) }) }) + When("the policy is invalid", func() { BeforeEach(func() { pathVariables["appId"] = TEST_APP_ID @@ -380,17 +381,18 @@ var _ = Describe("PublicApiHandler", func() { }) }) - When("providing extra fields", func() { - BeforeEach(func() { - pathVariables["appId"] = TEST_APP_ID - req, _ = http.NewRequest(http.MethodPut, "", bytes.NewBufferString(ValidPolicyStrWithExtraFields)) - schedulerStatus = 200 - }) - It("should succeed and ignore the extra fields", func() { - Expect(resp.Code).To(Equal(http.StatusOK)) - Expect(resp.Body).To(MatchJSON(ValidPolicyStr)) - }) - }) + // // 🚧🧐 To-do for the reviewer: Check if we can just ommit this test. + // When("providing extra fields", func() { + // BeforeEach(func() { + // pathVariables["appId"] = TEST_APP_ID + // req, _ = http.NewRequest(http.MethodPut, "", bytes.NewBufferString(ValidPolicyStrWithExtraFields)) + // schedulerStatus = 200 + // }) + // It("should succeed and ignore the extra fields", func() { + // Expect(resp.Code).To(Equal(http.StatusOK)) + // Expect(resp.Body).To(MatchJSON(ValidPolicyStr)) + // }) + // }) When("scheduler returns 204 status code", func() { BeforeEach(func() { @@ -420,7 +422,7 @@ var _ = Describe("PublicApiHandler", func() { schedulerStatus = 200 }) It("should not succeed and fail with 400", func() { - Expect(resp.Body.String()).To(MatchJSON(`[{"context":"(root).configuration.custom_metrics.metric_submission_strategy.allow_from","description":"configuration.custom_metrics.metric_submission_strategy.allow_from must be one of the following: \"bound_app\""}]`)) + Expect(resp.Body.String()).To(MatchJSON(`[{"context":"(root).configuration.custom_metrics.metric_submission_strategy.allow_from","description":"configuration.custom_metrics.metric_submission_strategy.allow_from must be one of the following: \"bound_app\", \"same_app\""}]`)) Expect(resp.Code).To(Equal(http.StatusBadRequest)) }) }) @@ -448,6 +450,7 @@ var _ = Describe("PublicApiHandler", func() { Expect(resp.Body).To(MatchJSON(validCustomMetricsConfigurationStr)) }) }) + When("configuration is removed but only policy is provided", func() { BeforeEach(func() { req = setupRequest(ValidPolicyStr, TEST_APP_ID, pathVariables) diff --git a/src/autoscaler/api/publicapiserver/publicapiserver_suite_test.go b/src/autoscaler/api/publicapiserver/publicapiserver_suite_test.go index 7b97bda06c..3c759d17e7 100644 --- a/src/autoscaler/api/publicapiserver/publicapiserver_suite_test.go +++ b/src/autoscaler/api/publicapiserver/publicapiserver_suite_test.go @@ -104,7 +104,7 @@ var _ = BeforeSuite(func() { CFServer: helpers.ServerConfig{ Port: 14000 + GinkgoParallelProcess(), }, - PolicySchemaPath: "../policyvalidator/policy_json.schema.json", + PolicySchemaPath: "../policyvalidator/scaling-policy.legacy-schema.json", Scheduler: config.SchedulerConfig{ SchedulerURL: schedulerServer.URL(), }, diff --git a/src/autoscaler/integration/components_test.go b/src/autoscaler/integration/components_test.go index 7c9d39f2d0..a36ad17fb5 100644 --- a/src/autoscaler/integration/components_test.go +++ b/src/autoscaler/integration/components_test.go @@ -232,7 +232,7 @@ func DefaultGolangAPITestConfig() apiConfig.Config { }, CatalogPath: "../servicebroker/config/catalog.json", CatalogSchemaPath: "../api/schemas/catalog.schema.json", - PolicySchemaPath: "../api/policyvalidator/policy_json.schema.json", + PolicySchemaPath: "../api/policyvalidator/scaling-policy.legacy-schema.json", InfoFilePath: "../api/exampleconfig/catalog-example.json", DashboardRedirectURI: "", CF: cf.Config{ From 2c69a85bf1106d3faf92f7209862d10bb195d6ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Weisbarth?= Date: Thu, 9 Oct 2025 15:46:30 +0200 Subject: [PATCH 07/20] Remove leftovers from old schema-file: Fix bosh-release; --- jobs/golangapiserver/templates/apiserver.yml.erb | 2 +- packages/golangapiserver/packaging | 2 +- src/autoscaler/api/default_config.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/jobs/golangapiserver/templates/apiserver.yml.erb b/jobs/golangapiserver/templates/apiserver.yml.erb index 629bb34b15..27f67f564d 100644 --- a/jobs/golangapiserver/templates/apiserver.yml.erb +++ b/jobs/golangapiserver/templates/apiserver.yml.erb @@ -86,7 +86,7 @@ broker_credentials: catalog_path: /var/vcap/jobs/golangapiserver/config/catalog.json catalog_schema_path: /var/vcap/packages/golangapiserver/catalog.schema.json info_file_path: /var/vcap/jobs/golangapiserver/config/info.json -policy_schema_path: /var/vcap/packages/golangapiserver/policy_json.schema.json +policy_schema_path: /var/vcap/packages/golangapiserver/scaling-policy.legacy-schema.json dashboard_redirect_uri: <%= p("autoscaler.apiserver.broker.server.dashboard_redirect_uri") %> default_credential_type: <%= p("autoscaler.apiserver.broker.default_credential_type") %> diff --git a/packages/golangapiserver/packaging b/packages/golangapiserver/packaging index 654bb4b777..29cbc4babc 100644 --- a/packages/golangapiserver/packaging +++ b/packages/golangapiserver/packaging @@ -13,5 +13,5 @@ cp --archive "${BOSH_COMPILE_TARGET}/autoscaler/build/api" "${BOSH_INSTALL_TARGE cp --archive "${BOSH_COMPILE_TARGET}/autoscaler/api/db/api.db.changelog.yml" "${BOSH_INSTALL_TARGET}" cp --archive "${BOSH_COMPILE_TARGET}/autoscaler/api/db/servicebroker.db.changelog.yaml" "${BOSH_INSTALL_TARGET}" -cp --archive "${BOSH_COMPILE_TARGET}/autoscaler/api/policyvalidator/policy_json.schema.json" "${BOSH_INSTALL_TARGET}" +cp --archive "${BOSH_COMPILE_TARGET}"/autoscaler/api/policyvalidator/*.json "${BOSH_INSTALL_TARGET}" # 🚧 To-do! Check if the files are found. cp --archive "${BOSH_COMPILE_TARGET}/autoscaler/api/catalog.schema.json" "${BOSH_INSTALL_TARGET}" diff --git a/src/autoscaler/api/default_config.json b/src/autoscaler/api/default_config.json index b960d13c88..f41d9b021e 100644 --- a/src/autoscaler/api/default_config.json +++ b/src/autoscaler/api/default_config.json @@ -9,7 +9,7 @@ }, "catalog_schema_path": "/home/vcap/app/api/schemas/catalog.schema.json", "info_file_path": "/home/vcap/app/api/default_info.json", - "policy_schema_path": "/home/vcap/app/api/policyvalidator/policy_json.schema.json", + "policy_schema_path": "/home/vcap/app/api/policyvalidator/scaling-policy.legacy-schema.json", "dashboard_redirect_uri": null, "default_credential_type": "binding-secret", "health": { From 318f6ad6775f4b33c6a3557fc0c3f6af2eae9960 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Weisbarth?= Date: Fri, 10 Oct 2025 11:07:20 +0200 Subject: [PATCH 08/20] =?UTF-8?q?=F0=9F=94=A7=20Fix=20Makefile;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Makefile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index ca701985ba..f7d2f60384 100644 --- a/Makefile +++ b/Makefile @@ -314,12 +314,12 @@ bosh-release: build/autoscaler-test.tgz_CI_true # already there for `go-mod-tidy` to work. See additional comment for that target in # ./src/autoscaler/Makefile. build/autoscaler-test.tgz: build_all go-mod-tidy go-mod-vendor - @echo " - creating bosh release into build/autoscaler-test.tgz"; \ - @bosh create-release --force --timestamp-version --tarball=build/autoscaler-test.tgz; \ + @echo ' - creating bosh release into build/autoscaler-test.tgz' + @bosh create-release --force --timestamp-version --tarball='build/autoscaler-test.tgz' build/autoscaler-test.tgz_CI_true: go-mod-tidy go-mod-vendor - @echo " - creating bosh release into ${AUTOSCALER_BOSH_TARBALL_PATH}" - @bosh create-release ${AUTOSCALER_BOSH_BUILD_OPTS} --version ${AUTOSCALER_BOSH_VERSION} --tarball=${AUTOSCALER_BOSH_TARBALL_PATH} + @echo ' - creating bosh release into ${AUTOSCALER_BOSH_TARBALL_PATH}' + @bosh create-release ${AUTOSCALER_BOSH_BUILD_OPTS} --version='${AUTOSCALER_BOSH_VERSION}' --tarball='${AUTOSCALER_BOSH_TARBALL_PATH}' .PHONY: generate-fakes autoscaler.generate-fakes test-app.generate-fakes generate-fakes: autoscaler.generate-fakes test-app.generate-fakes From 0cfcc4f877ea14a2f7a7fb51c9b0291d481a67b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Weisbarth?= Date: Fri, 10 Oct 2025 11:26:37 +0200 Subject: [PATCH 09/20] =?UTF-8?q?=F0=9F=A9=B9=20Introduce=20workaround=20f?= =?UTF-8?q?or=20bosh-compiled-releases.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- schema/json/Readme.md | 6 +- .../policy-configuration.legacy-schema.json | 41 +- .../scaling-policy.legacy-schema.json | 924 +++++++++++++++++- .../policyvalidator/shared_definitions.json | 11 +- 4 files changed, 978 insertions(+), 4 deletions(-) mode change 120000 => 100644 src/autoscaler/api/policyvalidator/policy-configuration.legacy-schema.json mode change 120000 => 100644 src/autoscaler/api/policyvalidator/scaling-policy.legacy-schema.json mode change 120000 => 100644 src/autoscaler/api/policyvalidator/shared_definitions.json diff --git a/schema/json/Readme.md b/schema/json/Readme.md index eec5278c3b..3e694c9c1b 100644 --- a/schema/json/Readme.md +++ b/schema/json/Readme.md @@ -1,3 +1,7 @@ # Read-me # -The currently used golang-library for json-schema, namely “[gojsonschema]()” not seems to be capable to resolve references to other files correctly across different directories. Perhaps not limited to but especially when referencing up the file-system-hierarchy (parent-directories). *Hint*: Use symbolic links to circumvent the issue! +The currently used golang-library for json-schema, namely “[gojsonschema]()” not seems to be capable to resolve references to other files correctly across different directories. Perhaps not limited to but especially when referencing up the file-system-hierarchy (parent-directories). In theory, symbolic links can be used to circumvent the issue … if there would not be another weakness in which we currently use in the workflow [bosh-release-checks.yaml](<../../../../.github/workflows/bosh-release-checks.yaml>) for making a compiled release: It can not handle symbolic links. Therefore it gets hard-linked here (which can not be tracked by git but it can somehow handle it!). + +After phasing out the bosh-technology of “Application Autoscaler”, these hardlinks can be removed. + +⚠️ This means the consinstence needs to be ensured manually. There is no CI/CD-check because Bosh is already in its phase-out for “Application Autoscaler”. diff --git a/src/autoscaler/api/policyvalidator/policy-configuration.legacy-schema.json b/src/autoscaler/api/policyvalidator/policy-configuration.legacy-schema.json deleted file mode 120000 index c754806e59..0000000000 --- a/src/autoscaler/api/policyvalidator/policy-configuration.legacy-schema.json +++ /dev/null @@ -1 +0,0 @@ -../../../../schema/json/policy-configuration.legacy-schema.json \ No newline at end of file diff --git a/src/autoscaler/api/policyvalidator/policy-configuration.legacy-schema.json b/src/autoscaler/api/policyvalidator/policy-configuration.legacy-schema.json new file mode 100644 index 0000000000..ff06aec9b8 --- /dev/null +++ b/src/autoscaler/api/policyvalidator/policy-configuration.legacy-schema.json @@ -0,0 +1,40 @@ +{ + "$schema": "http://json-schema.org/draft-05/schema#", + "title": "", + "description": "Schema for a scaling-policy.", + "type": "object", + + "properties": { + "custom_metrics": { + "type": "object", + "properties": { + "metric_submission_strategy": { + "type": "object", + "properties": { + "allow_from": { + "type": "string", + "enum": [ + "bound_app", + "same_app" + ] + } + }, + "required": [ + "allow_from" + ] + } + }, + "required": [ + "metric_submission_strategy" + ], + "additionalProperties": false + }, + "app_guid": { + "$ref": "./shared_definitions.json#/schemas/guid" + } + }, + "required": [ + "custom_metrics" + ], + "additionalProperties": false +} diff --git a/src/autoscaler/api/policyvalidator/scaling-policy.legacy-schema.json b/src/autoscaler/api/policyvalidator/scaling-policy.legacy-schema.json deleted file mode 120000 index 98ca85b397..0000000000 --- a/src/autoscaler/api/policyvalidator/scaling-policy.legacy-schema.json +++ /dev/null @@ -1 +0,0 @@ -../../../../schema/json/scaling-policy.legacy-schema.json \ No newline at end of file diff --git a/src/autoscaler/api/policyvalidator/scaling-policy.legacy-schema.json b/src/autoscaler/api/policyvalidator/scaling-policy.legacy-schema.json new file mode 100644 index 0000000000..18b7485c43 --- /dev/null +++ b/src/autoscaler/api/policyvalidator/scaling-policy.legacy-schema.json @@ -0,0 +1,923 @@ +{ + "$schema": "http://json-schema.org/draft-05/schema#", + "title": "Autoscaler Policy JSON Schema", + "description": "Schema for scaling-policies for Autoscaler", + "type": "object", + + "properties": { + "schema-version": { + "description": "Version-identifier for the used schema of this parameters-object.", + "type": "string", + "pattern": "^[0-9]+(\\.[0-9]+)?$" + }, + "credential-type": { + "type": "string", + "enum": [ + "x509", + "binding-secret" + ] + }, + "configuration": { + "$ref": "./policy-configuration.legacy-schema.json" + }, + "instance_min_count": { + "$id": "#/properties/instance_min_count", + "type": "integer", + "minimum": 1, + "title": "Minimum number of application instance always runs" + }, + "instance_max_count": { + "$id": "#/properties/instance_max_count", + "type": "integer", + "title": "Maximum how many instances of application can be provisioned as part of application scaling" + }, + "scaling_rules": { + "$id": "#/properties/scaling_rules", + "type": "array", + "title": "Dynamic Scaling_rules Schema", + "items": { + "$id": "#/properties/scaling_rules/items", + "type": "object", + "title": "Scaling_rules Items Schema", + "required": [ + "metric_type", + "threshold", + "operator", + "adjustment" + ], + "properties": { + "metric_type": { + "$id": "#/properties/scaling_rules/items/properties/metric_type", + "type": "string", + "title": "The Metric_type Schema", + "pattern": "^[a-zA-Z0-9_]+$", + "maxLength": 100 + }, + "breach_duration_secs": { + "$id": "#/properties/scaling_rules/items/properties/breach_duration_secs", + "type": "integer", + "title": "The Breach_duration_secs Schema", + "description": "The length of the past period when a scaling action might be triggered based on metric usage", + "maximum": 3600, + "minimum": 60 + }, + "threshold": { + "$id": "#/properties/scaling_rules/items/properties/threshold", + "type": "integer", + "title": "The Threshold Schema" + }, + "operator": { + "$id": "#/properties/scaling_rules/items/properties/operator", + "type": "string", + "title": "The Operator Schema", + "description": "Operator is used in combination with the threshold value to compare the current metric value", + "enum": [ + "<", + ">", + "<=", + ">=" + ] + }, + "cool_down_secs": { + "$id": "#/properties/scaling_rules/items/properties/cool_down_secs", + "type": "integer", + "title": "The Cool_down_secs Schema", + "description": "The interval between two successive scaling activity", + "maximum": 3600, + "minimum": 60 + }, + "adjustment": { + "$id": "#/properties/scaling_rules/items/properties/adjustment", + "type": "string", + "title": "The Adjustment Schema", + "description": "Magnitude of scaling in each step, +1 means scale up 1 Instance -2 means scale down 2 instances", + "pattern": "^[-+][1-9]+[0-9]*%?$" + } + } + } + }, + "schedules": { + "$id": "#/properties/schedules", + "type": "object", + "title": "The Scaling Schedules Schema", + "required": [ + "timezone" + ], + "anyOf": [ + { + "required": [ + "recurring_schedule" + ] + }, + { + "required": [ + "specific_date" + ] + } + ], + "properties": { + "timezone": { + "$id": "#/properties/schedules/properties/timezone", + "type": "string", + "title": "The Timezone Schema", + "pattern": "^(.*)$", + "enum": [ + "Etc/GMT+12", + "Etc/GMT+11", + "Pacific/Midway", + "Pacific/Niue", + "Pacific/Pago_Pago", + "Pacific/Samoa", + "US/Samoa", + "Etc/GMT+10", + "HST", + "Pacific/Honolulu", + "Pacific/Johnston", + "Pacific/Rarotonga", + "Pacific/Tahiti", + "US/Hawaii", + "Pacific/Marquesas", + "America/Adak", + "America/Atka", + "Etc/GMT+9", + "Pacific/Gambier", + "US/Aleutian", + "America/Anchorage", + "America/Juneau", + "America/Metlakatla", + "America/Nome", + "America/Sitka", + "America/Yakutat", + "Etc/GMT+8", + "Pacific/Pitcairn", + "US/Alaska", + "America/Creston", + "America/Dawson", + "America/Dawson_Creek", + "America/Ensenada", + "America/Hermosillo", + "America/Los_Angeles", + "America/Phoenix", + "America/Santa_Isabel", + "America/Tijuana", + "America/Vancouver", + "America/Whitehorse", + "Canada/Pacific", + "Canada/Yukon", + "Etc/GMT+7", + "MST", + "Mexico/BajaNorte", + "PST8PDT", + "US/Arizona", + "US/Pacific", + "US/Pacific-New", + "America/Belize", + "America/Boise", + "America/Cambridge_Bay", + "America/Chihuahua", + "America/Costa_Rica", + "America/Denver", + "America/Edmonton", + "America/El_Salvador", + "America/Guatemala", + "America/Inuvik", + "America/Managua", + "America/Mazatlan", + "America/Ojinaga", + "America/Regina", + "America/Shiprock", + "America/Swift_Current", + "America/Tegucigalpa", + "America/Yellowknife", + "Canada/East-Saskatchewan", + "Canada/Mountain", + "Canada/Saskatchewan", + "Etc/GMT+6", + "MST7MDT", + "Mexico/BajaSur", + "Navajo", + "Pacific/Galapagos", + "US/Mountain", + "America/Atikokan", + "America/Bahia_Banderas", + "America/Bogota", + "America/Cancun", + "America/Cayman", + "America/Chicago", + "America/Coral_Harbour", + "America/Eirunepe", + "America/Guayaquil", + "America/Indiana/Knox", + "America/Indiana/Tell_City", + "America/Jamaica", + "America/Knox_IN", + "America/Lima", + "America/Matamoros", + "America/Menominee", + "America/Merida", + "America/Mexico_City", + "America/Monterrey", + "America/North_Dakota/Beulah", + "America/North_Dakota/Center", + "America/North_Dakota/New_Salem", + "America/Panama", + "America/Porto_Acre", + "America/Rainy_River", + "America/Rankin_Inlet", + "America/Resolute", + "America/Rio_Branco", + "America/Winnipeg", + "Brazil/Acre", + "CST6CDT", + "Canada/Central", + "Chile/EasterIsland", + "EST", + "Etc/GMT+5", + "Jamaica", + "Mexico/General", + "Pacific/Easter", + "US/Central", + "US/Indiana-Starke", + "America/Caracas", + "America/Anguilla", + "America/Antigua", + "America/Aruba", + "America/Asuncion", + "America/Barbados", + "America/Blanc-Sablon", + "America/Boa_Vista", + "America/Campo_Grande", + "America/Cuiaba", + "America/Curacao", + "America/Detroit", + "America/Dominica", + "America/Fort_Wayne", + "America/Grand_Turk", + "America/Grenada", + "America/Guadeloupe", + "America/Guyana", + "America/Havana", + "America/Indiana/Indianapolis", + "America/Indiana/Marengo", + "America/Indiana/Petersburg", + "America/Indiana/Vevay", + "America/Indiana/Vincennes", + "America/Indiana/Winamac", + "America/Indianapolis", + "America/Iqaluit ", + "America/Kentucky/Louisville ", + "America/Kentucky/Monticello", + "America/Kralendijk", + "America/La_Paz", + "America/Louisville ", + "America/Lower_Princes", + "America/Manaus", + "America/Marigot", + "America/Martinique", + "America/Montreal", + "America/Montserrat", + "America/Nassau", + "America/New_York", + "America/Nipigon", + "America/Pangnirtung ", + "America/Port-au-Prince ", + "America/Port_of_Spain", + "America/Porto_Velho", + "America/Puerto_Rico ", + "America/Santo_Domingo ", + "America/St_Barthelemy", + "America/St_Kitts", + "America/St_Lucia", + "America/St_Thomas", + "America/St_Vincent", + "America/Thunder_Bay", + "America/Toronto", + "America/Tortola", + "America/Virgin", + "Brazil/West", + "Canada/Eastern", + "Cuba", + "EST5EDT", + "Etc/GMT+4", + "US/East-Indiana", + "US/Eastern", + "US/Michigan", + "America/Araguaina ", + "America/Argentina/Buenos_Aires ", + "America/Argentina/Catamarca ", + "America/Argentina/ComodRivadavia ", + "America/Argentina/Cordoba ", + "America/Argentina/Jujuy ", + "America/Argentina/La_Rioja ", + "America/Argentina/Mendoza ", + "America/Argentina/Rio_Gallegos ", + "America/Argentina/Salta ", + "America/Argentina/San_Juan ", + "America/Argentina/San_Luis ", + "America/Argentina/Tucuman ", + "America/Argentina/Ushuaia", + "America/Bahia", + "America/Belem", + "America/Buenos_Aires", + "America/Catamarca", + "America/Cayenne", + "America/Cordoba", + "America/Fortaleza", + "America/Glace_Bay", + "America/Goose_Bay", + "America/Halifax", + "America/Jujuy", + "America/Maceio", + "America/Mendoza", + "America/Moncton", + "America/Montevideo", + "America/Paramaribo", + "America/Recife", + "America/Rosario", + "America/Santarem", + "America/Santiago", + "America/Sao_Paulo", + "America/Thule", + "Antarctica/Palmer", + "Antarctica/Rothera", + "Atlantic/Bermuda", + "Atlantic/Stanley", + "Brazil/East", + "Canada/Atlantic", + "Chile/Continental", + "Etc/GMT+3", + "America/St_Johns", + "Canada/Newfoundland", + "America/Godthab", + "America/Miquelon", + "America/Noronha ", + "Atlantic/South_Georgia", + "Brazil/DeNoronha", + "Etc/GMT+2", + "Atlantic/Cape_Verde", + "Etc/GMT+1", + "Africa/Abidjan", + "Africa/Accra", + "Africa/Bamako", + "Africa/Banjul", + "Africa/Bissau", + "Africa/Conakry", + "Africa/Dakar", + "Africa/Freetown", + "Africa/Lome", + "Africa/Monrovia", + "Africa/Nouakchott", + "Africa/Ouagadougou", + "Africa/Sao_Tome", + "Africa/Timbuktu", + "America/Danmarkshavn", + "America/Scoresbysund", + "Atlantic/Azores", + "Atlantic/Reykjavik", + "Atlantic/St_Helena", + "Etc/GMT", + "Etc/GMT+0", + "Etc/GMT-0", + "Etc/GMT0", + "Etc/Greenwich", + "Etc/UCT", + "Etc/UTC", + "Etc/Universal", + "Etc/Zulu", + "GMT", + "GMT+0", + "GMT-0", + "GMT0", + "Greenwich", + "Iceland", + "UCT", + "UTC", + "Universal", + "Zulu", + "Africa/Algiers", + "Africa/Bangui", + "Africa/Brazzaville", + "Africa/Casablanca", + "Africa/Douala", + "Africa/El_Aaiun", + "Africa/Kinshasa", + "Africa/Lagos", + "Africa/Libreville", + "Africa/Luanda", + "Africa/Malabo", + "Africa/Ndjamena", + "Africa/Niamey", + "Africa/Porto-Novo", + "Africa/Tunis", + "Africa/Windhoek", + "Atlantic/Canary", + "Atlantic/Faeroe", + "Atlantic/Faroe", + "Atlantic/Madeira", + "Eire", + "Etc/GMT-1", + "Europe/Belfast", + "Europe/Dublin", + "Europe/Guernsey", + "Europe/Isle_of_Man", + "Europe/Jersey", + "Europe/Lisbon", + "Europe/London", + "GB", + "GB-Eire", + "Portugal", + "WET", + "Africa/Blantyre", + "Africa/Bujumbura", + "Africa/Cairo", + "Africa/Ceuta", + "Africa/Gaborone", + "Africa/Harare", + "Africa/Johannesburg", + "Africa/Kigali", + "Africa/Lubumbashi", + "Africa/Lusaka", + "Africa/Maputo", + "Africa/Maseru", + "Africa/Mbabane", + "Africa/Tripoli", + "Antarctica/Troll", + "Arctic/Longyearbyen", + "Atlantic/Jan_Mayen", + "CET", + "Egypt", + "Etc/GMT-2", + "Europe/Amsterdam", + "Europe/Andorra", + "Europe/Belgrade", + "Europe/Berlin", + "Europe/Bratislava", + "Europe/Brussels", + "Europe/Budapest", + "Europe/Busingen", + "Europe/Copenhagen", + "Europe/Gibraltar", + "Europe/Kaliningrad", + "Europe/Ljubljana", + "Europe/Luxembourg", + "Europe/Madrid", + "Europe/Malta", + "Europe/Monaco", + "Europe/Oslo", + "Europe/Paris", + "Europe/Podgorica", + "Europe/Prague", + "Europe/Rome", + "Europe/San_Marino", + "Europe/Sarajevo", + "Europe/Skopje", + "Europe/Stockholm", + "Europe/Tirane", + "Europe/Vaduz", + "Europe/Vatican", + "Europe/Vienna", + "Europe/Warsaw", + "Europe/Zagreb", + "Europe/Zurich", + "Libya", + "MET", + "Poland", + "Africa/Addis_Ababa", + "Africa/Asmara", + "Africa/Asmera", + "Africa/Dar_es_Salaam", + "Africa/Djibouti", + "Africa/Juba", + "Africa/Kampala", + "Africa/Khartoum", + "Africa/Mogadishu", + "Africa/Nairobi", + "Antarctica/Syowa", + "Asia/Aden", + "Asia/Amman", + "Asia/Baghdad", + "Asia/Bahrain", + "Asia/Beirut", + "Asia/Damascus", + "Asia/Gaza", + "Asia/Hebron", + "Asia/Istanbul", + "Asia/Jerusalem", + "Asia/Kuwait", + "Asia/Nicosia", + "Asia/Qatar", + "Asia/Riyadh", + "Asia/Tel_Aviv", + "EET", + "Etc/GMT-3", + "Europe/Athens", + "Europe/Bucharest", + "Europe/Chisinau", + "Europe/Helsinki", + "Europe/Istanbul", + "Europe/Kiev", + "Europe/Mariehamn", + "Europe/Minsk", + "Europe/Moscow", + "Europe/Nicosia", + "Europe/Riga", + "Europe/Simferopol", + "Europe/Sofia", + "Europe/Tallinn", + "Europe/Tiraspol", + "Europe/Uzhgorod", + "Europe/Vilnius", + "Europe/Volgograd", + "Europe/Zaporozhye", + "Indian/Antananarivo", + "Indian/Comoro", + "Indian/Mayotte", + "Israel", + "Turkey", + "W-SU", + "Asia/Dubai", + "Asia/Muscat", + "Asia/Tbilisi", + "Asia/Yerevan", + "Etc/GMT-4", + "Europe/Samara", + "Indian/Mahe", + "Indian/Mauritius", + "Indian/Reunion", + "Asia/Kabul", + "Asia/Tehran", + "Iran", + "Antarctica/Mawson", + "Asia/Aqtau", + "Asia/Aqtobe", + "Asia/Ashgabat", + "Asia/Ashkhabad", + "Asia/Baku", + "Asia/Dushanbe", + "Asia/Karachi", + "Asia/Oral", + "Asia/Samarkand", + "Asia/Tashkent", + "Asia/Yekaterinburg", + "Etc/GMT-5", + "Indian/Kerguelen", + "Indian/Maldives", + "Asia/Calcutta", + "Asia/Colombo", + "Asia/Kolkata", + "Asia/Kathmandu", + "Asia/Katmandu", + "Antarctica/Vostok", + "Asia/Almaty", + "Asia/Bishkek", + "Asia/Dacca", + "Asia/Dhaka", + "Asia/Kashgar", + "Asia/Novosibirsk", + "Asia/Omsk", + "Asia/Qyzylorda", + "Asia/Thimbu", + "Asia/Thimphu", + "Asia/Urumqi", + "Etc/GMT-6", + "Indian/Chagos", + "Asia/Rangoon", + "Indian/Cocos", + "Antarctica/Davis", + "Asia/Bangkok", + "Asia/Ho_Chi_Minh", + "Asia/Hovd", + "Asia/Jakarta", + "Asia/Krasnoyarsk", + "Asia/Novokuznetsk", + "Asia/Phnom_Penh", + "Asia/Pontianak", + "Asia/Saigon", + "Asia/Vientiane", + "Etc/GMT-7", + "Indian/Christmas", + "Antarctica/Casey", + "Asia/Brunei", + "Asia/Chita", + "Asia/Choibalsan", + "Asia/Chongqing", + "Asia/Chungking", + "Asia/Harbin", + "Asia/Hong_Kong", + "Asia/Irkutsk", + "Asia/Kuala_Lumpur", + "Asia/Kuching", + "Asia/Macao", + "Asia/Macau", + "Asia/Makassar", + "Asia/Manila", + "Asia/Shanghai", + "Asia/Singapore", + "Asia/Taipei", + "Asia/Ujung_Pandang", + "Asia/Ulaanbaatar", + "Asia/Ulan_Bator", + "Australia/Perth", + "Australia/West", + "Etc/GMT-8", + "Hongkong", + "PRC", + "ROC", + "Singapore", + "Australia/Eucla", + "Asia/Dili", + "Asia/Jayapura", + "Asia/Khandyga", + "Asia/Pyongyang", + "Asia/Seoul", + "Asia/Tokyo", + "Asia/Yakutsk", + "Etc/GMT-9", + "Japan", + "Pacific/Palau", + "ROK", + "Australia/Adelaide ", + "Australia/Broken_Hill", + "Australia/Darwin", + "Australia/North", + "Australia/South", + "Australia/Yancowinna ", + "Antarctica/DumontDUrville", + "Asia/Magadan", + "Asia/Sakhalin", + "Asia/Ust-Nera", + "Asia/Vladivostok", + "Australia/ACT", + "Australia/Brisbane", + "Australia/Canberra", + "Australia/Currie", + "Australia/Hobart", + "Australia/Lindeman", + "Australia/Melbourne", + "Australia/NSW", + "Australia/Queensland", + "Australia/Sydney", + "Australia/Tasmania", + "Australia/Victoria", + "Etc/GMT-10", + "Pacific/Chuuk", + "Pacific/Guam", + "Pacific/Port_Moresby", + "Pacific/Saipan", + "Pacific/Truk", + "Pacific/Yap", + "Australia/LHI", + "Australia/Lord_Howe", + "Antarctica/Macquarie", + "Asia/Srednekolymsk", + "Etc/GMT-11", + "Pacific/Bougainville", + "Pacific/Efate", + "Pacific/Guadalcanal", + "Pacific/Kosrae", + "Pacific/Noumea", + "Pacific/Pohnpei", + "Pacific/Ponape", + "Pacific/Norfolk", + "Antarctica/McMurdo", + "Antarctica/South_Pole", + "Asia/Anadyr", + "Asia/Kamchatka", + "Etc/GMT-12", + "Kwajalein", + "NZ", + "Pacific/Auckland", + "Pacific/Fiji", + "Pacific/Funafuti", + "Pacific/Kwajalein", + "Pacific/Majuro", + "Pacific/Nauru", + "Pacific/Tarawa", + "Pacific/Wake", + "Pacific/Wallis", + "NZ-CHAT", + "Pacific/Chatham", + "Etc/GMT-13", + "Pacific/Apia", + "Pacific/Enderbury", + "Pacific/Fakaofo", + "Pacific/Tongatapu", + "Etc/GMT-14", + "Pacific/Kiritimati" + ] + }, + "recurring_schedule": { + "$id": "#/properties/schedules/properties/recurring_schedule", + "type": "array", + "title": "The Recurring_schedule Schema", + "items": { + "$id": "#/properties/schedules/properties/recurring_schedule/items", + "type": "object", + "title": "The Recurring_schedule Items Schema", + "required": [ + "start_time", + "end_time", + "instance_min_count", + "instance_max_count" + ], + "oneOf": [ + { + "required": [ + "days_of_week" + ] + }, + { + "required": [ + "days_of_month" + ] + } + ], + "properties": { + "start_time": { + "$id": "#/properties/schedules/properties/recurring_schedule/items/properties/start_time", + "type": "string", + "title": "The Start_time Schema", + "pattern": "^(2[0-3]|1[0-9]|0[0-9]):([0-5][0-9])$" + }, + "end_time": { + "$id": "#/properties/schedules/properties/recurring_schedule/items/properties/end_time", + "type": "string", + "title": "The End_time Schema", + "pattern": "^(2[0-3]|1[0-9]|0[0-9]):([0-5][0-9])$" + }, + "days_of_week": { + "$id": "#/properties/schedules/properties/recurring_schedule/items/properties/days_of_week", + "type": "array", + "title": "The Days_of_week Schema", + "items": { + "$id": "#/properties/schedules/properties/recurring_schedule/items/properties/days_of_week/items", + "type": "integer", + "enum": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7 + ] + } + }, + "days_of_month": { + "$id": "#/properties/schedules/properties/recurring_schedule/items/properties/days_of_month", + "type": "array", + "title": "The Days_of_month Schema", + "items": { + "$id": "#/properties/schedules/properties/recurring_schedule/items/properties/days_of_month/items", + "type": "integer", + "enum": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31 + ] + } + }, + "instance_min_count": { + "$id": "#/properties/schedules/properties/recurring_schedule/items/properties/instance_min_count", + "type": "integer", + "title": "The Instance_min_count Schema" + }, + "instance_max_count": { + "$id": "#/properties/schedules/properties/recurring_schedule/items/properties/instance_max_count", + "type": "integer", + "title": "The Instance_max_count Schema" + }, + "initial_min_instance_count": { + "$id": "#/properties/schedules/properties/recurring_schedule/items/properties/initial_min_instance_count", + "type": "integer", + "title": "The Initial_min_instance_count Schema" + }, + "start_date": { + "oneOf": [ + { + "pattern": "^2[0-9]{3}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$", + "type": "string" + }, + { + "enum": [ + "" + ], + "type": "string" + } + ], + "description": "Start date of the recurrence in YYYY-MM-DD format" + }, + "end_date": { + "oneOf": [ + { + "pattern": "^2[0-9]{3}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$", + "type": "string" + }, + { + "enum": [ + "" + ], + "type": "string" + } + ], + "description": "End date of the recurrence in YYYY-MM-DD format" + } + } + } + }, + "specific_date": { + "$id": "#/properties/schedules/properties/specific_date", + "type": "array", + "title": "The Specific_date Schema", + "items": { + "$id": "#/properties/schedules/properties/specific_date/items", + "type": "object", + "title": "The Items Schema", + "required": [ + "start_date_time", + "end_date_time", + "instance_min_count", + "instance_max_count" + ], + "properties": { + "start_date_time": { + "$id": "#/properties/schedules/properties/specific_date/items/properties/start_date_time", + "type": "string", + "title": "The Start_date_time Schema", + "pattern": "^2[0-9]{3}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])T(2[0-3]|1[0-9]|0[0-9]):([0-5][0-9])$" + }, + "end_date_time": { + "$id": "#/properties/schedules/properties/specific_date/items/properties/end_date_time", + "type": "string", + "title": "The End_date_time Schema", + "default": "", + "pattern": "^2[0-9]{3}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])T(2[0-3]|1[0-9]|0[0-9]):([0-5][0-9])$" + }, + "instance_min_count": { + "$id": "#/properties/schedules/properties/specific_date/items/properties/instance_min_count", + "type": "integer", + "title": "The Instance_min_count Schema" + }, + "instance_max_count": { + "$id": "#/properties/schedules/properties/specific_date/items/properties/instance_max_count", + "type": "integer", + "title": "The Instance_max_count Schema" + }, + "initial_min_instance_count": { + "$id": "#/properties/schedules/properties/specific_date/items/properties/initial_min_instance_count", + "type": "integer", + "title": "The Initial_min_instance_count Schema" + } + } + } + } + } + } + }, + + "required": [ + "instance_min_count", + "instance_max_count" + ], + "anyOf": [ + { + "required": [ + "scaling_rules" + ] + }, + { + "required": [ + "schedules" + ] + } + ], + "additionalProperties": false +} diff --git a/src/autoscaler/api/policyvalidator/shared_definitions.json b/src/autoscaler/api/policyvalidator/shared_definitions.json deleted file mode 120000 index e1fc4df59e..0000000000 --- a/src/autoscaler/api/policyvalidator/shared_definitions.json +++ /dev/null @@ -1 +0,0 @@ -../../../../schema/json/shared_definitions.json \ No newline at end of file diff --git a/src/autoscaler/api/policyvalidator/shared_definitions.json b/src/autoscaler/api/policyvalidator/shared_definitions.json new file mode 100644 index 0000000000..46a6ae9315 --- /dev/null +++ b/src/autoscaler/api/policyvalidator/shared_definitions.json @@ -0,0 +1,10 @@ +{ + "schemas": { + "guid": { + "type": "string", + "description": "Unique identificator for a CF-resource, e.g. app, space, service-binding, …", + "pattern": "(\\d|[a-f]){8}-(\\d|[a-f]){4}-(\\d|[a-f]){4}-(\\d|[a-f]){4}-(\\d|[a-f]){12}", + "example": "8d0cee08-23ad-4813-a779-ad8118ea0b91" + } + } +} From 2240df172a87854c028b28f789c2b50cb53e7d09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Weisbarth?= Date: Fri, 10 Oct 2025 13:45:20 +0200 Subject: [PATCH 10/20] =?UTF-8?q?=F0=9F=94=A7=20Fix=20path=20to=20catalog;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/golangapiserver/packaging | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/golangapiserver/packaging b/packages/golangapiserver/packaging index 29cbc4babc..77e97c536b 100644 --- a/packages/golangapiserver/packaging +++ b/packages/golangapiserver/packaging @@ -1,6 +1,6 @@ set -e -x -export GOROOT=$(readlink -nf /var/vcap/packages/golang-1-linux) +export GOROOT=$(readlink --no-newline --canonicalize /var/vcap/packages/golang-1-linux) export PATH="${GOROOT}/bin:${PATH}" export GOPATH="${BOSH_COMPILE_TARGET}" export GOCACHE=/tmp/gocache @@ -13,5 +13,5 @@ cp --archive "${BOSH_COMPILE_TARGET}/autoscaler/build/api" "${BOSH_INSTALL_TARGE cp --archive "${BOSH_COMPILE_TARGET}/autoscaler/api/db/api.db.changelog.yml" "${BOSH_INSTALL_TARGET}" cp --archive "${BOSH_COMPILE_TARGET}/autoscaler/api/db/servicebroker.db.changelog.yaml" "${BOSH_INSTALL_TARGET}" -cp --archive "${BOSH_COMPILE_TARGET}"/autoscaler/api/policyvalidator/*.json "${BOSH_INSTALL_TARGET}" # 🚧 To-do! Check if the files are found. -cp --archive "${BOSH_COMPILE_TARGET}/autoscaler/api/catalog.schema.json" "${BOSH_INSTALL_TARGET}" +cp --archive "${BOSH_COMPILE_TARGET}"/autoscaler/api/policyvalidator/*.json "${BOSH_INSTALL_TARGET}" +cp --archive "${BOSH_COMPILE_TARGET}/autoscaler/api/schemas/catalog.schema.json" "${BOSH_INSTALL_TARGET}" From c12af7b2dce5c9e6a97286d96fc3764a4e3afaa7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Weisbarth?= Date: Mon, 13 Oct 2025 17:04:37 +0200 Subject: [PATCH 11/20] =?UTF-8?q?=F0=9F=94=A7=20Fix=20usage=20for=20legacy?= =?UTF-8?q?-parameter=20`stats=5Fwindow=5Fsecs`.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- schema/json/scaling-policy.legacy-schema.json | 7 ++ .../policyvalidator/policy_validator_test.go | 82 +++++++++---------- .../scaling-policy.legacy-schema.json | 7 ++ .../public_api_handler_test.go | 2 +- templates/app-autoscaler.yml | 2 +- 5 files changed, 57 insertions(+), 43 deletions(-) diff --git a/schema/json/scaling-policy.legacy-schema.json b/schema/json/scaling-policy.legacy-schema.json index 18b7485c43..67d6a7e6ff 100644 --- a/schema/json/scaling-policy.legacy-schema.json +++ b/schema/json/scaling-policy.legacy-schema.json @@ -61,6 +61,13 @@ "maximum": 3600, "minimum": 60 }, + "stats_window_secs": { + "$id": "#/properties/scaling_rules/items/properties/stats_window_secs", + "type": "integer", + "deprecated": true, + "title": "The stats_window_secs schema", + "description": "This is a legacy-parameter. 🏚️ It is silently ignored." + }, "threshold": { "$id": "#/properties/scaling_rules/items/properties/threshold", "type": "integer", diff --git a/src/autoscaler/api/policyvalidator/policy_validator_test.go b/src/autoscaler/api/policyvalidator/policy_validator_test.go index 249468f82a..acc7de580d 100644 --- a/src/autoscaler/api/policyvalidator/policy_validator_test.go +++ b/src/autoscaler/api/policyvalidator/policy_validator_test.go @@ -63,10 +63,10 @@ var _ = Describe("PolicyValidator", func() { policy, errResult = policyValidator.ParseAndValidatePolicy(json.RawMessage(policyString)) if policy != nil && len(errResult) <= 0 { policyDefinition = policy.GetPolicyDefinition() + policyBytes, err := json.Marshal(policyDefinition) + Expect(err).ToNot(HaveOccurred()) + policyJson = string(policyBytes) } - policyBytes, err := json.Marshal(policyDefinition) - Expect(err).ToNot(HaveOccurred()) - policyJson = string(policyBytes) }) Context("Policy Schema & Validation", func() { @@ -222,44 +222,44 @@ var _ = Describe("PolicyValidator", func() { }) }) - // // 🚧🧐 To-do for the reviewer: Check if we can just ommit this test. - // Context("when additional fields are present", func() { - // BeforeEach(func() { - // policyString = `{ - // "instance_max_count":4, - // "instance_min_count":1, - // "scaling_rules":[ - // { - // "metric_type":"memoryutil", - // "stats_window_secs": 600, - // "breach_duration_secs":600, - // "threshold":90, - // "operator":">=", - // "cool_down_secs":300, - // "adjustment":"+1" - // }], - // "is_admin": true, - // "is_sso": true, - // "role": "admin" - // }` - // }) - // It("the validation succeed and remove them", func() { - // validPolicyString := `{ - // "instance_max_count":4, - // "instance_min_count":1, - // "scaling_rules":[ - // { - // "metric_type":"memoryutil", - // "breach_duration_secs":600, - // "threshold":90, - // "operator":">=", - // "cool_down_secs":300, - // "adjustment":"+1" - // }] - // }` - // Expect(policyJson).To(MatchJSON(validPolicyString)) - // }) - // }) + // This needs to be passed for backwards-compatibility. We allowed in former times to set + // this parameter `stats_window_secs` via configuration. We must silently ignore this + // parameter today. + Context("when legacy-fields are present", func() { + BeforeEach(func() { + policyString = `{ + "instance_max_count":4, + "instance_min_count":1, + "scaling_rules":[ + { + "metric_type":"memoryutil", + "stats_window_secs": 600, + "breach_duration_secs":600, + "threshold":90, + "operator":">=", + "cool_down_secs":300, + "adjustment":"+1" + }] + }` + }) + It("the validation succeed and remove them", func() { + validPolicyString := `{ + "instance_max_count":4, + "instance_min_count":1, + "scaling_rules":[ + { + "metric_type":"memoryutil", + "breach_duration_secs":600, + "threshold":90, + "operator":">=", + "cool_down_secs":300, + "adjustment":"+1" + }] + }` + Expect(errResult).To(BeNil()) + Expect(policyJson).To(MatchJSON(validPolicyString)) + }) + }) Context("Scaling Rules", func() { diff --git a/src/autoscaler/api/policyvalidator/scaling-policy.legacy-schema.json b/src/autoscaler/api/policyvalidator/scaling-policy.legacy-schema.json index 18b7485c43..67d6a7e6ff 100644 --- a/src/autoscaler/api/policyvalidator/scaling-policy.legacy-schema.json +++ b/src/autoscaler/api/policyvalidator/scaling-policy.legacy-schema.json @@ -61,6 +61,13 @@ "maximum": 3600, "minimum": 60 }, + "stats_window_secs": { + "$id": "#/properties/scaling_rules/items/properties/stats_window_secs", + "type": "integer", + "deprecated": true, + "title": "The stats_window_secs schema", + "description": "This is a legacy-parameter. 🏚️ It is silently ignored." + }, "threshold": { "$id": "#/properties/scaling_rules/items/properties/threshold", "type": "integer", diff --git a/src/autoscaler/api/publicapiserver/public_api_handler_test.go b/src/autoscaler/api/publicapiserver/public_api_handler_test.go index d12e82097e..75439b5bf6 100644 --- a/src/autoscaler/api/publicapiserver/public_api_handler_test.go +++ b/src/autoscaler/api/publicapiserver/public_api_handler_test.go @@ -94,7 +94,7 @@ var _ = Describe("PublicApiHandler", func() { }] }, "is_admin": true - }` + }` // 🚧 To-do: ValidPolicyStrWithExtraFields is still not used in any test. InvalidCustomMetricsConfigurationStr = `{ "configuration": { "custom_metrics": { diff --git a/templates/app-autoscaler.yml b/templates/app-autoscaler.yml index 16da252a15..e42d207ba4 100644 --- a/templates/app-autoscaler.yml +++ b/templates/app-autoscaler.yml @@ -125,7 +125,7 @@ addons: stemcells: - alias: default os: ubuntu-jammy - version: latest + version: "1.915" # 🚧 To-do: Use "latest" again after successfully passing all tests; instance_groups: # Postgres Instance Group From f102249cc95830b37b7bd9394c9e50e1516892c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Weisbarth?= Date: Tue, 14 Oct 2025 10:55:51 +0200 Subject: [PATCH 12/20] =?UTF-8?q?=E2=86=91=F0=9F=93=A6=E2=9D=84=20Update?= =?UTF-8?q?=20Devbox-=20and=20Nix-environments;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- devbox.lock | 648 ++++++++++++++++++++++++------------------------- nix/flake.lock | 6 +- 2 files changed, 327 insertions(+), 327 deletions(-) diff --git a/devbox.lock b/devbox.lock index 05309843fa..b4cac3e2b1 100644 --- a/devbox.lock +++ b/devbox.lock @@ -50,8 +50,8 @@ } }, "actionlint@1.7.7": { - "last_modified": "2025-07-28T17:09:23Z", - "resolved": "github:NixOS/nixpkgs/648f70160c03151bc2121d179291337ad6bc564b#actionlint", + "last_modified": "2025-09-18T16:33:27Z", + "resolved": "github:NixOS/nixpkgs/f4b140d5b253f5e2a1ff4e5506edbf8267724bde#actionlint", "source": "devbox-search", "version": "1.7.7", "systems": { @@ -59,41 +59,41 @@ "outputs": [ { "name": "out", - "path": "/nix/store/hd1qpvgi2p0ma1rgci5k0dacmpnd461f-actionlint-1.7.7", + "path": "/nix/store/36dzsl32xcb815g0l80izpzd3dkg6363-actionlint-1.7.7", "default": true } ], - "store_path": "/nix/store/hd1qpvgi2p0ma1rgci5k0dacmpnd461f-actionlint-1.7.7" + "store_path": "/nix/store/36dzsl32xcb815g0l80izpzd3dkg6363-actionlint-1.7.7" }, "aarch64-linux": { "outputs": [ { "name": "out", - "path": "/nix/store/2ninnmhj64bxdzw8rdvd7kffqx9gkkpi-actionlint-1.7.7", + "path": "/nix/store/lvr86kzxypc85cllb6nzganrl7xy0ary-actionlint-1.7.7", "default": true } ], - "store_path": "/nix/store/2ninnmhj64bxdzw8rdvd7kffqx9gkkpi-actionlint-1.7.7" + "store_path": "/nix/store/lvr86kzxypc85cllb6nzganrl7xy0ary-actionlint-1.7.7" }, "x86_64-darwin": { "outputs": [ { "name": "out", - "path": "/nix/store/mc8bqhc96sqxnzznqxhmbmcg7asscbnk-actionlint-1.7.7", + "path": "/nix/store/r6zprynvg491pjm59qxlis796h38g0dz-actionlint-1.7.7", "default": true } ], - "store_path": "/nix/store/mc8bqhc96sqxnzznqxhmbmcg7asscbnk-actionlint-1.7.7" + "store_path": "/nix/store/r6zprynvg491pjm59qxlis796h38g0dz-actionlint-1.7.7" }, "x86_64-linux": { "outputs": [ { "name": "out", - "path": "/nix/store/vz8f7gjl7dmm2sl44xx6d3xvh39mq39w-actionlint-1.7.7", + "path": "/nix/store/jw9w3gbil62rxkpq4x6snfy7mfrnvvm6-actionlint-1.7.7", "default": true } ], - "store_path": "/nix/store/vz8f7gjl7dmm2sl44xx6d3xvh39mq39w-actionlint-1.7.7" + "store_path": "/nix/store/jw9w3gbil62rxkpq4x6snfy7mfrnvvm6-actionlint-1.7.7" } } }, @@ -174,8 +174,8 @@ } }, "bundix@2.5.2": { - "last_modified": "2025-08-11T07:05:29Z", - "resolved": "github:NixOS/nixpkgs/9585e9192aadc13ec3e49f33f8333bd3cda524df#bundix", + "last_modified": "2025-09-18T16:33:27Z", + "resolved": "github:NixOS/nixpkgs/f4b140d5b253f5e2a1ff4e5506edbf8267724bde#bundix", "source": "devbox-search", "version": "2.5.2", "systems": { @@ -183,47 +183,47 @@ "outputs": [ { "name": "out", - "path": "/nix/store/k51f0q2nxqr61kc9a6723vhrxkbh0630-bundix-2.5.2", + "path": "/nix/store/f87x413zz6smgprxyjh13d0jv2w3x8cs-bundix-2.5.2", "default": true } ], - "store_path": "/nix/store/k51f0q2nxqr61kc9a6723vhrxkbh0630-bundix-2.5.2" + "store_path": "/nix/store/f87x413zz6smgprxyjh13d0jv2w3x8cs-bundix-2.5.2" }, "aarch64-linux": { "outputs": [ { "name": "out", - "path": "/nix/store/z89lg0h7m5cvh8i4mbpvzplnmvhiz183-bundix-2.5.2", + "path": "/nix/store/jip2s1fs12wfr8dm20iav3r21dvr6w9n-bundix-2.5.2", "default": true } ], - "store_path": "/nix/store/z89lg0h7m5cvh8i4mbpvzplnmvhiz183-bundix-2.5.2" + "store_path": "/nix/store/jip2s1fs12wfr8dm20iav3r21dvr6w9n-bundix-2.5.2" }, "x86_64-darwin": { "outputs": [ { "name": "out", - "path": "/nix/store/vkxgz6wx2bdrd9dmk62812svn44ia7ma-bundix-2.5.2", + "path": "/nix/store/h1ac0kx1432jhmlqqia8ii6fm7b1gnz2-bundix-2.5.2", "default": true } ], - "store_path": "/nix/store/vkxgz6wx2bdrd9dmk62812svn44ia7ma-bundix-2.5.2" + "store_path": "/nix/store/h1ac0kx1432jhmlqqia8ii6fm7b1gnz2-bundix-2.5.2" }, "x86_64-linux": { "outputs": [ { "name": "out", - "path": "/nix/store/2q5zwdf80dbjjzfxrh4k7iqwj95fkcpa-bundix-2.5.2", + "path": "/nix/store/6ylhqbc4mp682d4lsgdjwzc1lj5z3qh0-bundix-2.5.2", "default": true } ], - "store_path": "/nix/store/2q5zwdf80dbjjzfxrh4k7iqwj95fkcpa-bundix-2.5.2" + "store_path": "/nix/store/6ylhqbc4mp682d4lsgdjwzc1lj5z3qh0-bundix-2.5.2" } } }, "cloudfoundry-cli@8.14.1": { - "last_modified": "2025-07-28T17:09:23Z", - "resolved": "github:NixOS/nixpkgs/648f70160c03151bc2121d179291337ad6bc564b#cloudfoundry-cli", + "last_modified": "2025-09-18T16:33:27Z", + "resolved": "github:NixOS/nixpkgs/f4b140d5b253f5e2a1ff4e5506edbf8267724bde#cloudfoundry-cli", "source": "devbox-search", "version": "8.14.1", "systems": { @@ -231,47 +231,47 @@ "outputs": [ { "name": "out", - "path": "/nix/store/qp7jnadfc0l714zszkf0snrcmwvj511d-cloudfoundry-cli-8.14.1", + "path": "/nix/store/3s5ann6axiiyn7xwxpdaz0bc75jsza08-cloudfoundry-cli-8.14.1", "default": true } ], - "store_path": "/nix/store/qp7jnadfc0l714zszkf0snrcmwvj511d-cloudfoundry-cli-8.14.1" + "store_path": "/nix/store/3s5ann6axiiyn7xwxpdaz0bc75jsza08-cloudfoundry-cli-8.14.1" }, "aarch64-linux": { "outputs": [ { "name": "out", - "path": "/nix/store/37x4dk4sn934vhbc5w1icga8lymc1mxf-cloudfoundry-cli-8.14.1", + "path": "/nix/store/skcfrhy3rd773x5rlpbxy0kgks92ql94-cloudfoundry-cli-8.14.1", "default": true } ], - "store_path": "/nix/store/37x4dk4sn934vhbc5w1icga8lymc1mxf-cloudfoundry-cli-8.14.1" + "store_path": "/nix/store/skcfrhy3rd773x5rlpbxy0kgks92ql94-cloudfoundry-cli-8.14.1" }, "x86_64-darwin": { "outputs": [ { "name": "out", - "path": "/nix/store/y0w6g0qi9v2d7ch870vxdn0hima0cins-cloudfoundry-cli-8.14.1", + "path": "/nix/store/w756qbq2yf4rl4j1sczspszrwcx5gc05-cloudfoundry-cli-8.14.1", "default": true } ], - "store_path": "/nix/store/y0w6g0qi9v2d7ch870vxdn0hima0cins-cloudfoundry-cli-8.14.1" + "store_path": "/nix/store/w756qbq2yf4rl4j1sczspszrwcx5gc05-cloudfoundry-cli-8.14.1" }, "x86_64-linux": { "outputs": [ { "name": "out", - "path": "/nix/store/9abzw2i33zpqs0b25fncq69m8r2dbp42-cloudfoundry-cli-8.14.1", + "path": "/nix/store/rsbw36lv9p6ahc5krgqqf6jjykjaz6yg-cloudfoundry-cli-8.14.1", "default": true } ], - "store_path": "/nix/store/9abzw2i33zpqs0b25fncq69m8r2dbp42-cloudfoundry-cli-8.14.1" + "store_path": "/nix/store/rsbw36lv9p6ahc5krgqqf6jjykjaz6yg-cloudfoundry-cli-8.14.1" } } }, "coreutils@latest": { - "last_modified": "2025-08-08T08:05:48Z", - "resolved": "github:NixOS/nixpkgs/a3f3e3f2c983e957af6b07a1db98bafd1f87b7a1#coreutils", + "last_modified": "2025-09-18T16:33:27Z", + "resolved": "github:NixOS/nixpkgs/f4b140d5b253f5e2a1ff4e5506edbf8267724bde#coreutils", "source": "devbox-search", "version": "9.7", "systems": { @@ -279,65 +279,65 @@ "outputs": [ { "name": "out", - "path": "/nix/store/7712hv9svx4cf3cc5g848aa073aak0a4-coreutils-9.7", + "path": "/nix/store/wbs75n9ffs3ac1pmn4fc7wqs0m9r1z3c-coreutils-9.7", "default": true }, { "name": "info", - "path": "/nix/store/06yc80769mip8qs0v04vmw32qhiy1hiy-coreutils-9.7-info" + "path": "/nix/store/6jlign71w02019282ibcb3yshnc5k0zp-coreutils-9.7-info" } ], - "store_path": "/nix/store/7712hv9svx4cf3cc5g848aa073aak0a4-coreutils-9.7" + "store_path": "/nix/store/wbs75n9ffs3ac1pmn4fc7wqs0m9r1z3c-coreutils-9.7" }, "aarch64-linux": { "outputs": [ { "name": "out", - "path": "/nix/store/8b7y59p9vzlkwbx52q42lzpf9gwkzih2-coreutils-9.7", + "path": "/nix/store/ics2w6dwhh4lvmv74d7axf4xc8b153wa-coreutils-9.7", "default": true }, { "name": "debug", - "path": "/nix/store/a465x241qnwmk8a7j8sryr3by1w43bry-coreutils-9.7-debug" + "path": "/nix/store/pcaxksk3kwxpvh2jcq62d7zci9had7y0-coreutils-9.7-debug" }, { "name": "info", - "path": "/nix/store/j571l41q05v8bzigwj98y5w8qv6y3ib8-coreutils-9.7-info" + "path": "/nix/store/krbf7q4winm2mji16fhz06wca585910d-coreutils-9.7-info" } ], - "store_path": "/nix/store/8b7y59p9vzlkwbx52q42lzpf9gwkzih2-coreutils-9.7" + "store_path": "/nix/store/ics2w6dwhh4lvmv74d7axf4xc8b153wa-coreutils-9.7" }, "x86_64-darwin": { "outputs": [ { "name": "out", - "path": "/nix/store/4kg0dzgzcwnm9cgn2adbgjavn50l9cyc-coreutils-9.7", + "path": "/nix/store/y7g1zx86rxgwyd88h0xiag8604v94x7f-coreutils-9.7", "default": true }, { "name": "info", - "path": "/nix/store/s5mamzn38dqib8vnsg6xkzjng6qhcrm5-coreutils-9.7-info" + "path": "/nix/store/jzpp0k3dnskvvkd3knnisxzy9v1apacv-coreutils-9.7-info" } ], - "store_path": "/nix/store/4kg0dzgzcwnm9cgn2adbgjavn50l9cyc-coreutils-9.7" + "store_path": "/nix/store/y7g1zx86rxgwyd88h0xiag8604v94x7f-coreutils-9.7" }, "x86_64-linux": { "outputs": [ { "name": "out", - "path": "/nix/store/ih779chzzag1nm91fgnrndml4mghm3la-coreutils-9.7", + "path": "/nix/store/8ksax0a2mxglr5hlkj2dzl556jx7xqn5-coreutils-9.7", "default": true }, { - "name": "debug", - "path": "/nix/store/djp1j1sr6znqdyklb60irysmbkr6b51h-coreutils-9.7-debug" + "name": "info", + "path": "/nix/store/0jcd383z6gslc471f17hmx0z4a0a7ach-coreutils-9.7-info" }, { - "name": "info", - "path": "/nix/store/qq91hijdh4gmwrkpx4q9158sk469n12n-coreutils-9.7-info" + "name": "debug", + "path": "/nix/store/fskcsdp5ya23myfdps6qc5y2sx6b4jw8-coreutils-9.7-debug" } ], - "store_path": "/nix/store/ih779chzzag1nm91fgnrndml4mghm3la-coreutils-9.7" + "store_path": "/nix/store/8ksax0a2mxglr5hlkj2dzl556jx7xqn5-coreutils-9.7" } } }, @@ -630,12 +630,12 @@ } }, "github:NixOS/nixpkgs/nixpkgs-unstable": { - "last_modified": "2025-09-13T06:53:53Z", - "resolved": "github:NixOS/nixpkgs/6d7ec06d6868ac6d94c371458fc2391ded9ff13d?lastModified=1757746433&narHash=sha256-fEvTiU4s9lWgW7mYEU%2F1QUPirgkn%2BodUBTaindgiziY%3D" + "last_modified": "2025-10-13T09:56:54Z", + "resolved": "github:NixOS/nixpkgs/c12c63cd6c5eb34c7b4c3076c6a99e00fcab86ec?lastModified=1760349414" }, "glibcLocales@latest": { - "last_modified": "2025-07-28T17:09:23Z", - "resolved": "github:NixOS/nixpkgs/648f70160c03151bc2121d179291337ad6bc564b#glibcLocales", + "last_modified": "2025-09-18T16:33:27Z", + "resolved": "github:NixOS/nixpkgs/f4b140d5b253f5e2a1ff4e5506edbf8267724bde#glibcLocales", "source": "devbox-search", "version": "2.40-66", "systems": { @@ -643,27 +643,27 @@ "outputs": [ { "name": "out", - "path": "/nix/store/3qf3dikps0lyifxs01mibkb019gzwfka-glibc-locales-2.40-66", + "path": "/nix/store/zjadyj68vh7mnngwngy4v80ydyf2w5i4-glibc-locales-2.40-66", "default": true } ], - "store_path": "/nix/store/3qf3dikps0lyifxs01mibkb019gzwfka-glibc-locales-2.40-66" + "store_path": "/nix/store/zjadyj68vh7mnngwngy4v80ydyf2w5i4-glibc-locales-2.40-66" }, "x86_64-linux": { "outputs": [ { "name": "out", - "path": "/nix/store/f01i3lw7r2mcyin7pfm6ww3sdyrpy9mb-glibc-locales-2.40-66", + "path": "/nix/store/008h0z2m22alg2v8kcdcw4v0f7c39lmm-glibc-locales-2.40-66", "default": true } ], - "store_path": "/nix/store/f01i3lw7r2mcyin7pfm6ww3sdyrpy9mb-glibc-locales-2.40-66" + "store_path": "/nix/store/008h0z2m22alg2v8kcdcw4v0f7c39lmm-glibc-locales-2.40-66" } } }, "gnumake@4.4.1": { - "last_modified": "2025-07-28T17:09:23Z", - "resolved": "github:NixOS/nixpkgs/648f70160c03151bc2121d179291337ad6bc564b#gnumake", + "last_modified": "2025-09-18T16:33:27Z", + "resolved": "github:NixOS/nixpkgs/f4b140d5b253f5e2a1ff4e5506edbf8267724bde#gnumake", "source": "devbox-search", "version": "4.4.1", "systems": { @@ -671,91 +671,91 @@ "outputs": [ { "name": "out", - "path": "/nix/store/8l8qhxbk9isvxvg22prkvqay1g7x8xh8-gnumake-4.4.1", + "path": "/nix/store/sjxx5p05vzq7xam62h21cyzkbyb1amvd-gnumake-4.4.1", "default": true }, { "name": "man", - "path": "/nix/store/d4dxxrdcri80kbzbkgnzw1bgjjq9ln4g-gnumake-4.4.1-man", + "path": "/nix/store/a4aay80xgirjm8hk1rd142qcd1kkfps8-gnumake-4.4.1-man", "default": true }, { "name": "info", - "path": "/nix/store/3jy0yby6jq6n5777rqya8913gr6wzdv5-gnumake-4.4.1-info" + "path": "/nix/store/cwx5agxi3ig3gmbk4c4dn7df2krzlddy-gnumake-4.4.1-info" } ], - "store_path": "/nix/store/8l8qhxbk9isvxvg22prkvqay1g7x8xh8-gnumake-4.4.1" + "store_path": "/nix/store/sjxx5p05vzq7xam62h21cyzkbyb1amvd-gnumake-4.4.1" }, "aarch64-linux": { "outputs": [ { "name": "out", - "path": "/nix/store/9ccm93c2lj2kb6m175grf8775w3yzvng-gnumake-4.4.1", + "path": "/nix/store/9cns3585v908dwbf5nfqqjghv955ndrq-gnumake-4.4.1", "default": true }, { "name": "man", - "path": "/nix/store/mnzb2cgp3hpvw3i5dn4bccs6ln4cnkpc-gnumake-4.4.1-man", + "path": "/nix/store/0a4l47b9sqc28ssi5hsq21ivs2hmbzcp-gnumake-4.4.1-man", "default": true }, { "name": "debug", - "path": "/nix/store/q92zl65186ayqg0f6vvhzldyi5bhpc70-gnumake-4.4.1-debug" + "path": "/nix/store/j8lcp5zjdq0l0ipvji7s13vdc53nzcki-gnumake-4.4.1-debug" }, { "name": "info", - "path": "/nix/store/ygnz9sgg6xbvvn6q4242jq9a4w0hfr57-gnumake-4.4.1-info" + "path": "/nix/store/8922q241lh4qbxd2g7jxsnjnkfmgap3z-gnumake-4.4.1-info" } ], - "store_path": "/nix/store/9ccm93c2lj2kb6m175grf8775w3yzvng-gnumake-4.4.1" + "store_path": "/nix/store/9cns3585v908dwbf5nfqqjghv955ndrq-gnumake-4.4.1" }, "x86_64-darwin": { "outputs": [ { "name": "out", - "path": "/nix/store/wwzvqkjzdqwrrwr600lygfq87j1cbvr5-gnumake-4.4.1", + "path": "/nix/store/fy063r4nqi1w79bklqhiv7ny0xwdqjp3-gnumake-4.4.1", "default": true }, { "name": "man", - "path": "/nix/store/xy024cz8x9hxbr3m1im6yk3bh8sd7q0w-gnumake-4.4.1-man", + "path": "/nix/store/g7nffhgbmv3r01199lhp0qz741kvnlvf-gnumake-4.4.1-man", "default": true }, { "name": "info", - "path": "/nix/store/38s0gpkmw3ripdv7iigqwwvdwgk88sb5-gnumake-4.4.1-info" + "path": "/nix/store/451pi5y9s89na99pxv6jjvqa44r08dha-gnumake-4.4.1-info" } ], - "store_path": "/nix/store/wwzvqkjzdqwrrwr600lygfq87j1cbvr5-gnumake-4.4.1" + "store_path": "/nix/store/fy063r4nqi1w79bklqhiv7ny0xwdqjp3-gnumake-4.4.1" }, "x86_64-linux": { "outputs": [ { "name": "out", - "path": "/nix/store/kzf67ka1wa2055bnsdrnqnv59md9xbxa-gnumake-4.4.1", + "path": "/nix/store/ahxj2q2mrl9z2k77ahqsl9j4zxq1wf84-gnumake-4.4.1", "default": true }, { "name": "man", - "path": "/nix/store/n414mxklk1mxyk9syhbbh6j0d92l4ggi-gnumake-4.4.1-man", + "path": "/nix/store/ha44mgbdcrzgah0dnjd28ax4hrdkc4mm-gnumake-4.4.1-man", "default": true }, { "name": "debug", - "path": "/nix/store/8vg51i45l7bqcc2qfcnjgppxlsfzi11h-gnumake-4.4.1-debug" + "path": "/nix/store/7vrxj6zy7y4a83d2q9585sxmcnkfs9ml-gnumake-4.4.1-debug" }, { "name": "info", - "path": "/nix/store/hs8b0bwzv4q3w8mf4pbq8l7v0vnjj0f9-gnumake-4.4.1-info" + "path": "/nix/store/m0ijkc5j3wdawh302pns9b45v9n6nq64-gnumake-4.4.1-info" } ], - "store_path": "/nix/store/kzf67ka1wa2055bnsdrnqnv59md9xbxa-gnumake-4.4.1" + "store_path": "/nix/store/ahxj2q2mrl9z2k77ahqsl9j4zxq1wf84-gnumake-4.4.1" } } }, "gnused@latest": { - "last_modified": "2025-07-28T17:09:23Z", - "resolved": "github:NixOS/nixpkgs/648f70160c03151bc2121d179291337ad6bc564b#gnused", + "last_modified": "2025-09-18T16:33:27Z", + "resolved": "github:NixOS/nixpkgs/f4b140d5b253f5e2a1ff4e5506edbf8267724bde#gnused", "source": "devbox-search", "version": "4.9", "systems": { @@ -763,63 +763,63 @@ "outputs": [ { "name": "out", - "path": "/nix/store/1299nwb4c57z3hamkfa33r1hf1cm73li-gnused-4.9", + "path": "/nix/store/zanfww82nmlb4b7mgblb779awsqb5rj7-gnused-4.9", "default": true }, { "name": "info", - "path": "/nix/store/3iq8pi0lkz0mhpmcwqbsq9qk0bfim6p0-gnused-4.9-info" + "path": "/nix/store/0qglacxr8f55w2g7f879silmbh27c38s-gnused-4.9-info" } ], - "store_path": "/nix/store/1299nwb4c57z3hamkfa33r1hf1cm73li-gnused-4.9" + "store_path": "/nix/store/zanfww82nmlb4b7mgblb779awsqb5rj7-gnused-4.9" }, "aarch64-linux": { "outputs": [ { "name": "out", - "path": "/nix/store/b6xhk3vpaa7xh4if3a5agm26b0xd29lk-gnused-4.9", + "path": "/nix/store/1r3nd7g6p0zbyyzmabypbxy7082llv64-gnused-4.9", "default": true }, { "name": "info", - "path": "/nix/store/klf1jsapqylamznp4ajf3d7y8lm1a1by-gnused-4.9-info" + "path": "/nix/store/kygl4yn2l9rkrzigb3cpndd09rxxpfa1-gnused-4.9-info" } ], - "store_path": "/nix/store/b6xhk3vpaa7xh4if3a5agm26b0xd29lk-gnused-4.9" + "store_path": "/nix/store/1r3nd7g6p0zbyyzmabypbxy7082llv64-gnused-4.9" }, "x86_64-darwin": { "outputs": [ { "name": "out", - "path": "/nix/store/ayvlyyh845f11a8y0j3h01gcz0f4xwr5-gnused-4.9", + "path": "/nix/store/qp4q4ixrxsnhnyh9h01fn5vnx7n3cdg9-gnused-4.9", "default": true }, { "name": "info", - "path": "/nix/store/ggy2kqzdiynzpkimb4sv3r17k5kqzcv7-gnused-4.9-info" + "path": "/nix/store/faxmcx3mzr91c4g46qy5bq3xlc0r61j0-gnused-4.9-info" } ], - "store_path": "/nix/store/ayvlyyh845f11a8y0j3h01gcz0f4xwr5-gnused-4.9" + "store_path": "/nix/store/qp4q4ixrxsnhnyh9h01fn5vnx7n3cdg9-gnused-4.9" }, "x86_64-linux": { "outputs": [ { "name": "out", - "path": "/nix/store/ql68miwsgz9094bi3qa7nk17bfwf6h6a-gnused-4.9", + "path": "/nix/store/pmhkmqy0vxk47r6ndh0azybhf6gs6k25-gnused-4.9", "default": true }, { "name": "info", - "path": "/nix/store/pg0x36jmj9b3kbfhasgx7gr6p0k24jhi-gnused-4.9-info" + "path": "/nix/store/50m785l8aaqhy28h0jwi0rd02wjlrzb4-gnused-4.9-info" } ], - "store_path": "/nix/store/ql68miwsgz9094bi3qa7nk17bfwf6h6a-gnused-4.9" + "store_path": "/nix/store/pmhkmqy0vxk47r6ndh0azybhf6gs6k25-gnused-4.9" } } }, "gnutar@latest": { - "last_modified": "2025-07-28T17:09:23Z", - "resolved": "github:NixOS/nixpkgs/648f70160c03151bc2121d179291337ad6bc564b#gnutar", + "last_modified": "2025-09-18T16:33:27Z", + "resolved": "github:NixOS/nixpkgs/f4b140d5b253f5e2a1ff4e5506edbf8267724bde#gnutar", "source": "devbox-search", "version": "1.35", "systems": { @@ -827,63 +827,63 @@ "outputs": [ { "name": "out", - "path": "/nix/store/8q719jjpny4yszxjk02aag9k1swjj4dn-gnutar-1.35", + "path": "/nix/store/3l2jw31r5051xiwmz5gr2d71lwb8zv5d-gnutar-1.35", "default": true }, { "name": "info", - "path": "/nix/store/scm78yjrmm7d6cprj8gq7sdp7156ask4-gnutar-1.35-info" + "path": "/nix/store/f19pb2ha1ardvdywyasjzh1p1q6hrqsn-gnutar-1.35-info" } ], - "store_path": "/nix/store/8q719jjpny4yszxjk02aag9k1swjj4dn-gnutar-1.35" + "store_path": "/nix/store/3l2jw31r5051xiwmz5gr2d71lwb8zv5d-gnutar-1.35" }, "aarch64-linux": { "outputs": [ { "name": "out", - "path": "/nix/store/3xzjsrjrgdpf95ygk9xjnv88xpjm8819-gnutar-1.35", + "path": "/nix/store/q4g8q49zsdy8n57l9iqxvh3ragf0h4h7-gnutar-1.35", "default": true }, { "name": "info", - "path": "/nix/store/2plpdshw2bcf0kd9f1371x4wrv1bgvwg-gnutar-1.35-info" + "path": "/nix/store/yzqx812lyvwa15ydaa0c45sgmh3mygv3-gnutar-1.35-info" } ], - "store_path": "/nix/store/3xzjsrjrgdpf95ygk9xjnv88xpjm8819-gnutar-1.35" + "store_path": "/nix/store/q4g8q49zsdy8n57l9iqxvh3ragf0h4h7-gnutar-1.35" }, "x86_64-darwin": { "outputs": [ { "name": "out", - "path": "/nix/store/k7kw6wi1dbhgd0y5z4krmsj94fibxk32-gnutar-1.35", + "path": "/nix/store/fq5n0ck0wwn77749vh79w1i2ldyjqnxz-gnutar-1.35", "default": true }, { "name": "info", - "path": "/nix/store/fr4qf4k4pl184zi7k7f5g6yxn3kgk7r0-gnutar-1.35-info" + "path": "/nix/store/s14cf82d6l3rbprxpin6dwps7y0imgjb-gnutar-1.35-info" } ], - "store_path": "/nix/store/k7kw6wi1dbhgd0y5z4krmsj94fibxk32-gnutar-1.35" + "store_path": "/nix/store/fq5n0ck0wwn77749vh79w1i2ldyjqnxz-gnutar-1.35" }, "x86_64-linux": { "outputs": [ { "name": "out", - "path": "/nix/store/bpn20jn4235mij1372xvpmibgzzpqa3m-gnutar-1.35", + "path": "/nix/store/8av8pfs7bnyc6hqj764ns4z1fnr9bva1-gnutar-1.35", "default": true }, { "name": "info", - "path": "/nix/store/zid2ypv4vwwmgkwbkpn3akycmac2zkk7-gnutar-1.35-info" + "path": "/nix/store/whva2v1nm9906mjvp72higb492mvsk6s-gnutar-1.35-info" } ], - "store_path": "/nix/store/bpn20jn4235mij1372xvpmibgzzpqa3m-gnutar-1.35" + "store_path": "/nix/store/8av8pfs7bnyc6hqj764ns4z1fnr9bva1-gnutar-1.35" } } }, "go-tools@2025.1": { - "last_modified": "2025-07-28T17:09:23Z", - "resolved": "github:NixOS/nixpkgs/648f70160c03151bc2121d179291337ad6bc564b#go-tools", + "last_modified": "2025-09-18T16:33:27Z", + "resolved": "github:NixOS/nixpkgs/f4b140d5b253f5e2a1ff4e5506edbf8267724bde#go-tools", "source": "devbox-search", "version": "2025.1.1", "systems": { @@ -891,41 +891,41 @@ "outputs": [ { "name": "out", - "path": "/nix/store/nc7qyp9x1xig9izzq809spg0519ls8xb-go-tools-2025.1.1", + "path": "/nix/store/a9g84xfpv2fclghbw2zd346wxkn8pfrk-go-tools-2025.1.1", "default": true } ], - "store_path": "/nix/store/nc7qyp9x1xig9izzq809spg0519ls8xb-go-tools-2025.1.1" + "store_path": "/nix/store/a9g84xfpv2fclghbw2zd346wxkn8pfrk-go-tools-2025.1.1" }, "aarch64-linux": { "outputs": [ { "name": "out", - "path": "/nix/store/6khv96k8lqllh7fczywdkds6rz5625jr-go-tools-2025.1.1", + "path": "/nix/store/3x30sdf9ai0rxdcp2awdli89z72gipiy-go-tools-2025.1.1", "default": true } ], - "store_path": "/nix/store/6khv96k8lqllh7fczywdkds6rz5625jr-go-tools-2025.1.1" + "store_path": "/nix/store/3x30sdf9ai0rxdcp2awdli89z72gipiy-go-tools-2025.1.1" }, "x86_64-darwin": { "outputs": [ { "name": "out", - "path": "/nix/store/s2krlwsslxhj7w3q71r6ra5ipm15c5dr-go-tools-2025.1.1", + "path": "/nix/store/b968qmp7mrzgwff09cbz3bq6s8md9cnl-go-tools-2025.1.1", "default": true } ], - "store_path": "/nix/store/s2krlwsslxhj7w3q71r6ra5ipm15c5dr-go-tools-2025.1.1" + "store_path": "/nix/store/b968qmp7mrzgwff09cbz3bq6s8md9cnl-go-tools-2025.1.1" }, "x86_64-linux": { "outputs": [ { "name": "out", - "path": "/nix/store/70klkla08ys9frzabdvwlxxw4xzd7q14-go-tools-2025.1.1", + "path": "/nix/store/1mpnrivqfwmzdwr6n4pwpy9wsx7slfh1-go-tools-2025.1.1", "default": true } ], - "store_path": "/nix/store/70klkla08ys9frzabdvwlxxw4xzd7q14-go-tools-2025.1.1" + "store_path": "/nix/store/1mpnrivqfwmzdwr6n4pwpy9wsx7slfh1-go-tools-2025.1.1" } } }, @@ -1170,8 +1170,8 @@ } }, "jq@latest": { - "last_modified": "2025-08-12T09:17:37Z", - "resolved": "github:NixOS/nixpkgs/372d9eeeafa5b15913201e2b92e8e539ac7c64d1#jq", + "last_modified": "2025-09-21T09:21:16Z", + "resolved": "github:NixOS/nixpkgs/a1f79a1770d05af18111fbbe2a3ab2c42c0f6cd0#jq", "source": "devbox-search", "version": "1.8.1", "systems": { @@ -1179,109 +1179,109 @@ "outputs": [ { "name": "bin", - "path": "/nix/store/bk70k4fzjkki438jhl73ry55amwhvzkd-jq-1.8.1-bin", + "path": "/nix/store/8cadjdrc1gjc66ijgn2wnmfj6yajnxmb-jq-1.8.1-bin", "default": true }, { "name": "man", - "path": "/nix/store/vn6dfky85mpw670m4c2zi61cvjcx1asj-jq-1.8.1-man", + "path": "/nix/store/11rdl4l7v5gswf5gdizk02jy39bw7bby-jq-1.8.1-man", "default": true }, { - "name": "dev", - "path": "/nix/store/4jjfl7vg6y26npsx078850sr5lghx8mi-jq-1.8.1-dev" + "name": "out", + "path": "/nix/store/i8v8j94vx41c1wfzp1n69ddbrrf192pq-jq-1.8.1" }, { - "name": "doc", - "path": "/nix/store/j8nb6pqjccz7j4nn4mqmx92yvgl31ajl-jq-1.8.1-doc" + "name": "dev", + "path": "/nix/store/vcjkcdi02h123i073sxma5kfhps9z2fd-jq-1.8.1-dev" }, { - "name": "out", - "path": "/nix/store/z7npa6zipbnn7akq0dzpvp6ldc53qvbl-jq-1.8.1" + "name": "doc", + "path": "/nix/store/sbr5199a3y3vpx1kaphyl4nnjlpzzzym-jq-1.8.1-doc" } ], - "store_path": "/nix/store/bk70k4fzjkki438jhl73ry55amwhvzkd-jq-1.8.1-bin" + "store_path": "/nix/store/8cadjdrc1gjc66ijgn2wnmfj6yajnxmb-jq-1.8.1-bin" }, "aarch64-linux": { "outputs": [ { "name": "bin", - "path": "/nix/store/k881xdkfjqnyaclrq5n1lfxjnv1z70ds-jq-1.8.1-bin", + "path": "/nix/store/ync89vi4g1xnkj4fxspc63zfvs7dk8aw-jq-1.8.1-bin", "default": true }, { "name": "man", - "path": "/nix/store/51fwmry2hkrsdnzb9nngwhffm0rnha72-jq-1.8.1-man", + "path": "/nix/store/44k1613ynml3cgx5v9k6saqw994hqcl9-jq-1.8.1-man", "default": true }, { - "name": "dev", - "path": "/nix/store/zbw60md1qi8bif7k5qmh9l4an8hx924g-jq-1.8.1-dev" + "name": "out", + "path": "/nix/store/hz4c9q3baf434zw2y0yzb3a5kkj3rhwl-jq-1.8.1" }, { - "name": "doc", - "path": "/nix/store/k19ngx2hsicd6qvl5lxx878ag9443pwq-jq-1.8.1-doc" + "name": "dev", + "path": "/nix/store/194yri6cyqad6yvbhpqp5wswsppnsi7x-jq-1.8.1-dev" }, { - "name": "out", - "path": "/nix/store/5sq5gjdf3v9pc4b78mfx1v9vkzx65dhk-jq-1.8.1" + "name": "doc", + "path": "/nix/store/cjmvz6ma3qnhdvapjf2yghw28lrah0ja-jq-1.8.1-doc" } ], - "store_path": "/nix/store/k881xdkfjqnyaclrq5n1lfxjnv1z70ds-jq-1.8.1-bin" + "store_path": "/nix/store/ync89vi4g1xnkj4fxspc63zfvs7dk8aw-jq-1.8.1-bin" }, "x86_64-darwin": { "outputs": [ { "name": "bin", - "path": "/nix/store/n9hbqknz3fxayw3c4y2l7yipa7n975ic-jq-1.8.1-bin", + "path": "/nix/store/8kcm1dcivx14cp5z39wzma81jbrvaazs-jq-1.8.1-bin", "default": true }, { "name": "man", - "path": "/nix/store/46h6qyk0f9436w8pcvgx7h59j0ic41iv-jq-1.8.1-man", + "path": "/nix/store/88l2hgigy77vjgkdjps6l6vl8svxgaaa-jq-1.8.1-man", "default": true }, - { - "name": "doc", - "path": "/nix/store/ac3lal7kk1vbri37b2v5c1r8dq8356qs-jq-1.8.1-doc" - }, { "name": "out", - "path": "/nix/store/n94wp81gr2ifwzy6fzc8andk4h2cmnia-jq-1.8.1" + "path": "/nix/store/ladmn1j7zikwdmih15d8rfh7z550y1q2-jq-1.8.1" }, { "name": "dev", - "path": "/nix/store/frdhk9q6bvdpx6pjspxvp56wqmj5xrwr-jq-1.8.1-dev" + "path": "/nix/store/wjxxw199ix3mkg8ms6k0hqfg7swxr2qv-jq-1.8.1-dev" + }, + { + "name": "doc", + "path": "/nix/store/17mfk267mjhnvgbm03w0scsfq82a65na-jq-1.8.1-doc" } ], - "store_path": "/nix/store/n9hbqknz3fxayw3c4y2l7yipa7n975ic-jq-1.8.1-bin" + "store_path": "/nix/store/8kcm1dcivx14cp5z39wzma81jbrvaazs-jq-1.8.1-bin" }, "x86_64-linux": { "outputs": [ { "name": "bin", - "path": "/nix/store/kwxm52f2g9ap890pfj2j4ryzq2gj2i69-jq-1.8.1-bin", + "path": "/nix/store/7jvwwz45qap70i6asxzcnbshhz88a5sv-jq-1.8.1-bin", "default": true }, { "name": "man", - "path": "/nix/store/pdh9j4z29n3m1xahvssji96cfgk21a43-jq-1.8.1-man", + "path": "/nix/store/laqc7c2c9j09vm1w58vmj633vc2wb3wv-jq-1.8.1-man", "default": true }, { - "name": "out", - "path": "/nix/store/mmi8dxjdsv8r9jxnyd3dqwqakxda1796-jq-1.8.1" + "name": "doc", + "path": "/nix/store/j572lmsgrx4a9bim6gwlyn9mnlf67490-jq-1.8.1-doc" }, { - "name": "dev", - "path": "/nix/store/h0xayyfsl9f17bss0x1xhhz7c3n5fq43-jq-1.8.1-dev" + "name": "out", + "path": "/nix/store/byi56qh6h63rdhfjh4plnyndfcpqx13p-jq-1.8.1" }, { - "name": "doc", - "path": "/nix/store/j9idg8al8k1fs1v3sm6axc9zsd8zj5vn-jq-1.8.1-doc" + "name": "dev", + "path": "/nix/store/5rp4imr3xn3qwwxpgmss2q9pj8bak9wy-jq-1.8.1-dev" } ], - "store_path": "/nix/store/kwxm52f2g9ap890pfj2j4ryzq2gj2i69-jq-1.8.1-bin" + "store_path": "/nix/store/7jvwwz45qap70i6asxzcnbshhz88a5sv-jq-1.8.1-bin" } } }, @@ -1334,8 +1334,8 @@ } }, "maven@3.9.11": { - "last_modified": "2025-07-28T17:09:23Z", - "resolved": "github:NixOS/nixpkgs/648f70160c03151bc2121d179291337ad6bc564b#maven", + "last_modified": "2025-09-18T16:33:27Z", + "resolved": "github:NixOS/nixpkgs/f4b140d5b253f5e2a1ff4e5506edbf8267724bde#maven", "source": "devbox-search", "version": "3.9.11", "systems": { @@ -1343,41 +1343,41 @@ "outputs": [ { "name": "out", - "path": "/nix/store/4l03gxm9lnkap9z4s219lk2lmznf6ksr-maven-3.9.11", + "path": "/nix/store/rzhr4g6jwsib6szxwji7kqj9bbc87vq6-maven-3.9.11", "default": true } ], - "store_path": "/nix/store/4l03gxm9lnkap9z4s219lk2lmznf6ksr-maven-3.9.11" + "store_path": "/nix/store/rzhr4g6jwsib6szxwji7kqj9bbc87vq6-maven-3.9.11" }, "aarch64-linux": { "outputs": [ { "name": "out", - "path": "/nix/store/6663sm7x2b6lh3lcy40ysng365h0n41w-maven-3.9.11", + "path": "/nix/store/0n3y4r6ilszcw1r5ya426ig4cb4ammm8-maven-3.9.11", "default": true } ], - "store_path": "/nix/store/6663sm7x2b6lh3lcy40ysng365h0n41w-maven-3.9.11" + "store_path": "/nix/store/0n3y4r6ilszcw1r5ya426ig4cb4ammm8-maven-3.9.11" }, "x86_64-darwin": { "outputs": [ { "name": "out", - "path": "/nix/store/i1fz4dsqcfy2ilz9yq0z84n973iw4k8z-maven-3.9.11", + "path": "/nix/store/8ni22mh86cmzc4gw5x2g7xm1nbwi5l1c-maven-3.9.11", "default": true } ], - "store_path": "/nix/store/i1fz4dsqcfy2ilz9yq0z84n973iw4k8z-maven-3.9.11" + "store_path": "/nix/store/8ni22mh86cmzc4gw5x2g7xm1nbwi5l1c-maven-3.9.11" }, "x86_64-linux": { "outputs": [ { "name": "out", - "path": "/nix/store/f055dmaqf8japp7nqww78zp3g37j5qfs-maven-3.9.11", + "path": "/nix/store/ngdc0ikxrpvdicdchs8146y2xdy83wfj-maven-3.9.11", "default": true } ], - "store_path": "/nix/store/f055dmaqf8japp7nqww78zp3g37j5qfs-maven-3.9.11" + "store_path": "/nix/store/ngdc0ikxrpvdicdchs8146y2xdy83wfj-maven-3.9.11" } } }, @@ -1437,8 +1437,8 @@ } }, "openssl@latest": { - "last_modified": "2025-08-12T09:17:37Z", - "resolved": "github:NixOS/nixpkgs/372d9eeeafa5b15913201e2b92e8e539ac7c64d1#openssl", + "last_modified": "2025-09-21T09:21:16Z", + "resolved": "github:NixOS/nixpkgs/a1f79a1770d05af18111fbbe2a3ab2c42c0f6cd0#openssl", "source": "devbox-search", "version": "3.5.1", "systems": { @@ -1446,306 +1446,306 @@ "outputs": [ { "name": "bin", - "path": "/nix/store/izq1292gji1xs6m3x68b8qx7zqan05f8-openssl-3.5.1-bin", + "path": "/nix/store/bpawzvf8z4yjmwr3zc7haxhv99sl8s2a-openssl-3.5.1-bin", "default": true }, { "name": "man", - "path": "/nix/store/0l182727myjmvfzsy8gx6inh3x504il3-openssl-3.5.1-man", + "path": "/nix/store/2jh1wcwhjylfxzly4hbb5fz55b1lxxm5-openssl-3.5.1-man", "default": true }, - { - "name": "dev", - "path": "/nix/store/ng9za9qmgb7bvyjamx0c3y647d9aprmp-openssl-3.5.1-dev" - }, { "name": "doc", - "path": "/nix/store/ggbmkvwiw1s919lyqqk75xks4v2cdbiw-openssl-3.5.1-doc" + "path": "/nix/store/69p0m85qi4rw0ka8jqciba0p9q3140b0-openssl-3.5.1-doc" }, { "name": "out", - "path": "/nix/store/v7ip9q2908xcmq4i9wray4w1g81qb3sc-openssl-3.5.1" + "path": "/nix/store/0ais7wnqw8xzj0331c2jka53s6g14wqb-openssl-3.5.1" + }, + { + "name": "dev", + "path": "/nix/store/4fwifkd3zn4m6y7zacyhpwy5frj63knk-openssl-3.5.1-dev" } ], - "store_path": "/nix/store/izq1292gji1xs6m3x68b8qx7zqan05f8-openssl-3.5.1-bin" + "store_path": "/nix/store/bpawzvf8z4yjmwr3zc7haxhv99sl8s2a-openssl-3.5.1-bin" }, "aarch64-linux": { "outputs": [ { "name": "bin", - "path": "/nix/store/xzmj7xk823r8lmjy6sjsg2g4blxybfi3-openssl-3.5.1-bin", + "path": "/nix/store/4zzrcin7jdph1ybm7pkwlypv4khmqgf3-openssl-3.5.1-bin", "default": true }, { "name": "man", - "path": "/nix/store/vr911qc1hr53s8m6ylymp4cvhwqi45mv-openssl-3.5.1-man", + "path": "/nix/store/slgd9x3x372g5bm73qbijj41rqb560fd-openssl-3.5.1-man", "default": true }, { - "name": "dev", - "path": "/nix/store/1p4cdalnyisvhlkl8w73q4qnns06ydvj-openssl-3.5.1-dev" + "name": "out", + "path": "/nix/store/rzlvprd99wlbiv2wsqgp23kmxhkm1yfr-openssl-3.5.1" }, { - "name": "doc", - "path": "/nix/store/xq02qv12hlmhpz1109h7bp165i0a716r-openssl-3.5.1-doc" + "name": "debug", + "path": "/nix/store/n0r6fn7sd0bvmpwm8s5nlmm626jilcra-openssl-3.5.1-debug" }, { - "name": "out", - "path": "/nix/store/mcjp51nvbchqx54r6vhm718vjrdjb2a2-openssl-3.5.1" + "name": "dev", + "path": "/nix/store/hg5ryywl9xqg82kvzwvqkx4m2yckkdsg-openssl-3.5.1-dev" }, { - "name": "debug", - "path": "/nix/store/vwnqrwx87w232ch5dlihngsc35sf048r-openssl-3.5.1-debug" + "name": "doc", + "path": "/nix/store/91mrccm5jwv94w8lvh7c0wf0cygj0yal-openssl-3.5.1-doc" } ], - "store_path": "/nix/store/xzmj7xk823r8lmjy6sjsg2g4blxybfi3-openssl-3.5.1-bin" + "store_path": "/nix/store/4zzrcin7jdph1ybm7pkwlypv4khmqgf3-openssl-3.5.1-bin" }, "x86_64-darwin": { "outputs": [ { "name": "bin", - "path": "/nix/store/2h8gv6njdcsiq3z2raqjk3g0wz0kzzlw-openssl-3.5.1-bin", + "path": "/nix/store/4w92hq61lhdzin9mkvzlxvd603pgwm9w-openssl-3.5.1-bin", "default": true }, { "name": "man", - "path": "/nix/store/4zgwnvcfz96amr18cqprlnma8hw1hjl9-openssl-3.5.1-man", + "path": "/nix/store/h59wasb1qrmvsgz79bl0sqnrhx0vccha-openssl-3.5.1-man", "default": true }, { "name": "dev", - "path": "/nix/store/hniscv0s0f4kjbl2shclml5q4ag5pymd-openssl-3.5.1-dev" + "path": "/nix/store/63827r05nfpr7bg23zpivb9sn33cshy4-openssl-3.5.1-dev" }, { "name": "doc", - "path": "/nix/store/b7r9rf7m7n3096jifgqv7gaddx42v7p9-openssl-3.5.1-doc" + "path": "/nix/store/3kbg9sqs4i8j7rkr6q7gb25c0bjqylyr-openssl-3.5.1-doc" }, { "name": "out", - "path": "/nix/store/9pcqqs75c8lbimwzndvklpxjkjl2f009-openssl-3.5.1" + "path": "/nix/store/v3cq87zwjd4f91y0i1023kkb9wvwc71z-openssl-3.5.1" } ], - "store_path": "/nix/store/2h8gv6njdcsiq3z2raqjk3g0wz0kzzlw-openssl-3.5.1-bin" + "store_path": "/nix/store/4w92hq61lhdzin9mkvzlxvd603pgwm9w-openssl-3.5.1-bin" }, "x86_64-linux": { "outputs": [ { "name": "bin", - "path": "/nix/store/vwggl55yh9lba643r5avc78n7cmmbi2a-openssl-3.5.1-bin", + "path": "/nix/store/nn4b544v4sanvsf22mjiw3qh8mwh6pzh-openssl-3.5.1-bin", "default": true }, { "name": "man", - "path": "/nix/store/57mz84gznx0ljg972m5ws4kcg3s1wdss-openssl-3.5.1-man", + "path": "/nix/store/kmyzbfp60f9b85lhpr3njswxlm76b0av-openssl-3.5.1-man", "default": true }, { - "name": "debug", - "path": "/nix/store/3kmhc9kdw1niw1hn7xfnixhm7irgws2r-openssl-3.5.1-debug" + "name": "doc", + "path": "/nix/store/g9nxr4sig9dkhfvgc0ma1qb6fs3xm5dn-openssl-3.5.1-doc" }, { - "name": "dev", - "path": "/nix/store/b97gjl5zygaf6vzxsa1lf7jih8q4xi00-openssl-3.5.1-dev" + "name": "out", + "path": "/nix/store/gi615r79j260ihhzdkhrg6qva9wfrbyy-openssl-3.5.1" }, { - "name": "doc", - "path": "/nix/store/a9m4vmx5ch8jq4xdmf8sy2bn1qxl2s8j-openssl-3.5.1-doc" + "name": "debug", + "path": "/nix/store/rj7yspi9mw9zcbma7v3h2zbh03bkjb82-openssl-3.5.1-debug" }, { - "name": "out", - "path": "/nix/store/lyl9yxxz8a3mlaxvm0jln6mglpbf2fha-openssl-3.5.1" + "name": "dev", + "path": "/nix/store/qqfiw89h8j4pilcyqapldzq5vf0vqgxy-openssl-3.5.1-dev" } ], - "store_path": "/nix/store/vwggl55yh9lba643r5avc78n7cmmbi2a-openssl-3.5.1-bin" + "store_path": "/nix/store/nn4b544v4sanvsf22mjiw3qh8mwh6pzh-openssl-3.5.1-bin" } } }, "postgresql@latest": { - "last_modified": "2025-08-12T09:17:37Z", + "last_modified": "2025-09-21T09:21:16Z", "plugin_version": "0.0.2", - "resolved": "github:NixOS/nixpkgs/372d9eeeafa5b15913201e2b92e8e539ac7c64d1#postgresql", + "resolved": "github:NixOS/nixpkgs/a1f79a1770d05af18111fbbe2a3ab2c42c0f6cd0#postgresql", "source": "devbox-search", - "version": "17.5", + "version": "17.6", "systems": { "aarch64-darwin": { "outputs": [ { "name": "out", - "path": "/nix/store/dfmi5df0i45v2cibv90zbga22l5pmmnw-postgresql-17.5", + "path": "/nix/store/x8316kdj4hvr90zww4fzrh6iqbp2fwfv-postgresql-17.6", "default": true }, { "name": "man", - "path": "/nix/store/g3gynlyaxxgwiq8fm5lcqs7cp0fr25zl-postgresql-17.5-man", + "path": "/nix/store/s8fy60163fvin1rypqp49xff5vfq8pc1-postgresql-17.6-man", "default": true }, { - "name": "lib", - "path": "/nix/store/z2ixx0168lngnhdgcxaw9w6wra0ibnnx-postgresql-17.5-lib" + "name": "dev", + "path": "/nix/store/kdsy2qhdaj0drwv7bjlqrq8iwg7am4pm-postgresql-17.6-dev" }, { - "name": "plperl", - "path": "/nix/store/8qv982x7a177gwn2d0s2xnss9gayhj51-postgresql-17.5-plperl" + "name": "plpython3", + "path": "/nix/store/k52nrq2chmf9bcsgdl5xdxigi43cb641-postgresql-17.6-plpython3" }, { - "name": "plpython3", - "path": "/nix/store/fqkh3qj0x8by1aczhg5sj2wla0rmg3wr-postgresql-17.5-plpython3" + "name": "pltcl", + "path": "/nix/store/95s1q5ybh6g7rff0sb77963rxmzl07hb-postgresql-17.6-pltcl" }, { "name": "doc", - "path": "/nix/store/13n7szqbq83d5s7i17xd1y6vijnlw8si-postgresql-17.5-doc" + "path": "/nix/store/p598qxn9a6czkawqica9aglgpi7qk602-postgresql-17.6-doc" }, { - "name": "dev", - "path": "/nix/store/rid24asr9anzmzvj8vzvvh6vhyzrv1g0-postgresql-17.5-dev" + "name": "lib", + "path": "/nix/store/8jvg8lb3r1r4g7fchvn71kigclgj93ss-postgresql-17.6-lib" }, { "name": "jit", - "path": "/nix/store/pwi2jpd8kzpddzcj6rnhas1rkd17j05l-postgresql-17.5-jit" + "path": "/nix/store/hhwgaaprw190fd4lan9c1jcayni005mc-postgresql-17.6-jit" }, { - "name": "pltcl", - "path": "/nix/store/bvfy276k5xz806vglghvbl7s8c6wl5z4-postgresql-17.5-pltcl" + "name": "plperl", + "path": "/nix/store/7i8fin94kv6bsil9yfws868kfn8dsfk5-postgresql-17.6-plperl" } ], - "store_path": "/nix/store/dfmi5df0i45v2cibv90zbga22l5pmmnw-postgresql-17.5" + "store_path": "/nix/store/x8316kdj4hvr90zww4fzrh6iqbp2fwfv-postgresql-17.6" }, "aarch64-linux": { "outputs": [ { "name": "out", - "path": "/nix/store/mdf05bq8zlvraxpxlyj3rg6660x3ramx-postgresql-17.5", + "path": "/nix/store/zdmrsczynsanljim77c5fhmlgf8lnqgr-postgresql-17.6", "default": true }, { "name": "man", - "path": "/nix/store/z39cmrls5696pv6a99kglyyw309z2lj9-postgresql-17.5-man", + "path": "/nix/store/izkz6kkch9br4rcn3jzijds6galnswmj-postgresql-17.6-man", "default": true }, { - "name": "dev", - "path": "/nix/store/l7rryvxw8z6im8dnsmskpry4ydbnk6rq-postgresql-17.5-dev" + "name": "plpython3", + "path": "/nix/store/4539wyz2xpa70ihhbsfbizqj2a4nb0qi-postgresql-17.6-plpython3" }, { - "name": "doc", - "path": "/nix/store/5g0krnrsbwmpvwz50jk7if7az8q9yxvp-postgresql-17.5-doc" + "name": "plperl", + "path": "/nix/store/89plna3bfrlihpdl6h1nif7488j4lycw-postgresql-17.6-plperl" }, { - "name": "lib", - "path": "/nix/store/06mkcha74k49nzjg5zdlf8ywv2ij77sm-postgresql-17.5-lib" + "name": "debug", + "path": "/nix/store/661ssr2ma5jah0ifj0ca3pjhxz8fmgv8-postgresql-17.6-debug" }, { - "name": "plperl", - "path": "/nix/store/l7g0spdxs7wfhzlfz6584krb4wxbl0hn-postgresql-17.5-plperl" + "name": "dev", + "path": "/nix/store/w9d09r1ziky5yjdpq0fb0lkpm93db6rv-postgresql-17.6-dev" }, { - "name": "plpython3", - "path": "/nix/store/wivl4xjnsdka9cz3aiv5y7fg7rqg7jfp-postgresql-17.5-plpython3" + "name": "jit", + "path": "/nix/store/w856mf7gc0y81jsjppm77ww9k7l04dm6-postgresql-17.6-jit" }, { - "name": "jit", - "path": "/nix/store/3jflknpljm3hfr03fih3rwm18wdxdwkh-postgresql-17.5-jit" + "name": "lib", + "path": "/nix/store/b2l7jsirdac28nsih5y1y2i6ml7khlbh-postgresql-17.6-lib" }, { - "name": "debug", - "path": "/nix/store/s84wvrgpqql4iw9gygq5jzs93c7bvv90-postgresql-17.5-debug" + "name": "doc", + "path": "/nix/store/bfgv1xi0r72hwy7sg2syz9mvrmm1iq6a-postgresql-17.6-doc" }, { "name": "pltcl", - "path": "/nix/store/n58hxn83kdxmhd2hx1jhbn9bca07595j-postgresql-17.5-pltcl" + "path": "/nix/store/kbxy78mf481232li36wvfcl2749xqlb1-postgresql-17.6-pltcl" } ], - "store_path": "/nix/store/mdf05bq8zlvraxpxlyj3rg6660x3ramx-postgresql-17.5" + "store_path": "/nix/store/zdmrsczynsanljim77c5fhmlgf8lnqgr-postgresql-17.6" }, "x86_64-darwin": { "outputs": [ { "name": "out", - "path": "/nix/store/dh5vca89l71qprnlhk8syb79c544s8wd-postgresql-17.5", + "path": "/nix/store/hfq4hh6nji29lrkd2d2h499s4rnfjvxr-postgresql-17.6", "default": true }, { "name": "man", - "path": "/nix/store/1q81qzabr82rn36zs9ll6s8c6briqbbv-postgresql-17.5-man", + "path": "/nix/store/iv7n6gfg8vfjghhsnc8szdpx8nljnwjr-postgresql-17.6-man", "default": true }, { - "name": "dev", - "path": "/nix/store/c6mk6kvrchibfmjc9fia8i0d064mfl51-postgresql-17.5-dev" - }, - { - "name": "pltcl", - "path": "/nix/store/x7ngrwcymp5zmqm62qf5wixirsdm74vm-postgresql-17.5-pltcl" + "name": "lib", + "path": "/nix/store/nigqc3d59kp0mlknain2ywd1kxzhh84a-postgresql-17.6-lib" }, { "name": "plperl", - "path": "/nix/store/q4s9pzl97bf4lkxlwsamwb0q3w611ldy-postgresql-17.5-plperl" + "path": "/nix/store/4ywicb8zvp2qv0wslisgh9khd3f3mq8y-postgresql-17.6-plperl" }, { "name": "plpython3", - "path": "/nix/store/kvk8x0lphwfd5nkncv7ixn8j37964ihg-postgresql-17.5-plpython3" + "path": "/nix/store/fxiq5vdvb7zamdj467dn4i5jgfvwcdj3-postgresql-17.6-plpython3" }, { - "name": "jit", - "path": "/nix/store/dwlbnv8qs5m3sz4vdln9d9bz6rilc5r6-postgresql-17.5-jit" + "name": "pltcl", + "path": "/nix/store/zixqyfqp3df8cjxrggyv24r2mn6q03q4-postgresql-17.6-pltcl" }, { - "name": "doc", - "path": "/nix/store/1sh044b2grn7xd40afrqa56lvh1i4bkh-postgresql-17.5-doc" + "name": "dev", + "path": "/nix/store/1ln3lngxzr913r6nh3qj605x82ijc5r7-postgresql-17.6-dev" }, { - "name": "lib", - "path": "/nix/store/83xc3vq9vmaix9ab0cx849ypnbcajv5q-postgresql-17.5-lib" + "name": "jit", + "path": "/nix/store/rvjip61mh1a2llmhwgrd08hvsbcnb59j-postgresql-17.6-jit" + }, + { + "name": "doc", + "path": "/nix/store/s6gdj1jblsimi551jaw9a0ab3r6208sl-postgresql-17.6-doc" } ], - "store_path": "/nix/store/dh5vca89l71qprnlhk8syb79c544s8wd-postgresql-17.5" + "store_path": "/nix/store/hfq4hh6nji29lrkd2d2h499s4rnfjvxr-postgresql-17.6" }, "x86_64-linux": { "outputs": [ { "name": "out", - "path": "/nix/store/f1akpy48ng3zshls7ncfx0h45ca9kskg-postgresql-17.5", + "path": "/nix/store/jq2kbdw6ljv9i47jz23pm072cfyxwpfj-postgresql-17.6", "default": true }, { "name": "man", - "path": "/nix/store/vrqqycznilgqy95rfrxp7ji9l8swdlc7-postgresql-17.5-man", + "path": "/nix/store/z2s4zb4kxh80v7npbin8pv27vjf5fc4k-postgresql-17.6-man", "default": true }, { - "name": "jit", - "path": "/nix/store/1ymacxkxm8z5v9yhh196gv82462vrja8-postgresql-17.5-jit" + "name": "dev", + "path": "/nix/store/l8m7mbvqxdi9bd5apl8s49kjpnzrcv6c-postgresql-17.6-dev" }, { - "name": "plperl", - "path": "/nix/store/3yjd6qmiz4965rwa3fz4pi2cvdzki63d-postgresql-17.5-plperl" + "name": "doc", + "path": "/nix/store/dg0cwp756r82crxmdv8vzq7d7kjzi4qi-postgresql-17.6-doc" }, { - "name": "plpython3", - "path": "/nix/store/x3g44jhfkzkdxziy8122fz4djh8hi6ia-postgresql-17.5-plpython3" + "name": "plperl", + "path": "/nix/store/cq3zxs5dw2xy0hib0fpi70k4kack640z-postgresql-17.6-plperl" }, { "name": "debug", - "path": "/nix/store/p9qmqlj43crbvya5zic4daxpa9irpcf6-postgresql-17.5-debug" + "path": "/nix/store/hzkqv89nrdz00npy3r5ly7hi8iq6i9s4-postgresql-17.6-debug" }, { - "name": "dev", - "path": "/nix/store/dhvvss0cly7inw5m5gg00zaksn1x4k0a-postgresql-17.5-dev" + "name": "jit", + "path": "/nix/store/w6f1f7dxai435w963fzifbf14kxbv5s3-postgresql-17.6-jit" }, { - "name": "pltcl", - "path": "/nix/store/sfjhv0zx9mklr23n9ybfwmlggw13ciy7-postgresql-17.5-pltcl" + "name": "lib", + "path": "/nix/store/msjxcqa4x2f52dyq10rbrbw6k0m0hi90-postgresql-17.6-lib" }, { - "name": "doc", - "path": "/nix/store/wy4x55s5idkpjwdc38icsjj5fai7qr35-postgresql-17.5-doc" + "name": "plpython3", + "path": "/nix/store/sjb555ik5jrrk2gllpgcdmvwxhj5kv1v-postgresql-17.6-plpython3" }, { - "name": "lib", - "path": "/nix/store/n8z6i9wdbv4wkckw88fcf85pjpydvdmw-postgresql-17.5-lib" + "name": "pltcl", + "path": "/nix/store/0w5sqnpakfk7qfm1yfbkwajz75pha4qj-postgresql-17.6-pltcl" } ], - "store_path": "/nix/store/f1akpy48ng3zshls7ncfx0h45ca9kskg-postgresql-17.5" + "store_path": "/nix/store/jq2kbdw6ljv9i47jz23pm072cfyxwpfj-postgresql-17.6" } } }, @@ -1855,8 +1855,8 @@ } }, "ripgrep@14.1.1": { - "last_modified": "2025-07-28T17:09:23Z", - "resolved": "github:NixOS/nixpkgs/648f70160c03151bc2121d179291337ad6bc564b#ripgrep", + "last_modified": "2025-09-18T16:33:27Z", + "resolved": "github:NixOS/nixpkgs/f4b140d5b253f5e2a1ff4e5506edbf8267724bde#ripgrep", "source": "devbox-search", "version": "14.1.1", "systems": { @@ -1864,41 +1864,41 @@ "outputs": [ { "name": "out", - "path": "/nix/store/md9kfvsz7axcb5b1z2yw2mybi3lhxyha-ripgrep-14.1.1", + "path": "/nix/store/3slzsxhg7zv8zyqvd841q4d7lnax27wy-ripgrep-14.1.1", "default": true } ], - "store_path": "/nix/store/md9kfvsz7axcb5b1z2yw2mybi3lhxyha-ripgrep-14.1.1" + "store_path": "/nix/store/3slzsxhg7zv8zyqvd841q4d7lnax27wy-ripgrep-14.1.1" }, "aarch64-linux": { "outputs": [ { "name": "out", - "path": "/nix/store/slgpwy2f6j68p47hifz503251dgxb075-ripgrep-14.1.1", + "path": "/nix/store/ysiy4dfvfi84s85myinrp1vm2cs3cmrw-ripgrep-14.1.1", "default": true } ], - "store_path": "/nix/store/slgpwy2f6j68p47hifz503251dgxb075-ripgrep-14.1.1" + "store_path": "/nix/store/ysiy4dfvfi84s85myinrp1vm2cs3cmrw-ripgrep-14.1.1" }, "x86_64-darwin": { "outputs": [ { "name": "out", - "path": "/nix/store/m645jkssqpw05acf1cnz037via2y0j4q-ripgrep-14.1.1", + "path": "/nix/store/f8kiqis4pf3i400waah45y5m799s0d0w-ripgrep-14.1.1", "default": true } ], - "store_path": "/nix/store/m645jkssqpw05acf1cnz037via2y0j4q-ripgrep-14.1.1" + "store_path": "/nix/store/f8kiqis4pf3i400waah45y5m799s0d0w-ripgrep-14.1.1" }, "x86_64-linux": { "outputs": [ { "name": "out", - "path": "/nix/store/1ijacjhy42pqx7vfi5mnsqrps2k3b8xf-ripgrep-14.1.1", + "path": "/nix/store/5pv8jrp70w0flz9g3yqkk7fzcnr28mpx-ripgrep-14.1.1", "default": true } ], - "store_path": "/nix/store/1ijacjhy42pqx7vfi5mnsqrps2k3b8xf-ripgrep-14.1.1" + "store_path": "/nix/store/5pv8jrp70w0flz9g3yqkk7fzcnr28mpx-ripgrep-14.1.1" } } }, @@ -1968,8 +1968,8 @@ } }, "shellcheck@0.10.0": { - "last_modified": "2025-07-28T17:09:23Z", - "resolved": "github:NixOS/nixpkgs/648f70160c03151bc2121d179291337ad6bc564b#shellcheck", + "last_modified": "2025-09-18T16:33:27Z", + "resolved": "github:NixOS/nixpkgs/f4b140d5b253f5e2a1ff4e5506edbf8267724bde#shellcheck", "source": "devbox-search", "version": "0.10.0", "systems": { @@ -1977,97 +1977,97 @@ "outputs": [ { "name": "bin", - "path": "/nix/store/3a2z1gjjws8i5jih5nl9qv8gigs0dd1a-shellcheck-0.10.0-bin", + "path": "/nix/store/dxppq6y4mb663r0li716pavrahwh9sws-shellcheck-0.10.0-bin", "default": true }, { "name": "man", - "path": "/nix/store/jh1bwqic2r17gycqka783ddqrdq4yfih-shellcheck-0.10.0-man", + "path": "/nix/store/7lpymai82rrcps6z7zl4q5j69w3pp5ng-shellcheck-0.10.0-man", "default": true }, { "name": "doc", - "path": "/nix/store/a4six21byq4jxv2jxbgv0rqdagr0cd89-shellcheck-0.10.0-doc", + "path": "/nix/store/0wbb09lk7bx9ywc453a8nnw41hc8qp1i-shellcheck-0.10.0-doc", "default": true }, { "name": "out", - "path": "/nix/store/avf1jjk5y72179cm3aljdx0rqdbxcasg-shellcheck-0.10.0" + "path": "/nix/store/ffxba7sh87j0vg759cjm7qmcadsmbfw7-shellcheck-0.10.0" } ], - "store_path": "/nix/store/3a2z1gjjws8i5jih5nl9qv8gigs0dd1a-shellcheck-0.10.0-bin" + "store_path": "/nix/store/dxppq6y4mb663r0li716pavrahwh9sws-shellcheck-0.10.0-bin" }, "aarch64-linux": { "outputs": [ { "name": "bin", - "path": "/nix/store/01lx1jxzs82ka6xyxmsn2i59ii8x7mqz-shellcheck-0.10.0-bin", + "path": "/nix/store/kvhcnjzmjyqc641yd57f7g26nraw64sm-shellcheck-0.10.0-bin", "default": true }, { "name": "man", - "path": "/nix/store/ysxil8f5r4qascqhpfb6ixb8p1sqpabl-shellcheck-0.10.0-man", + "path": "/nix/store/2ps0gaalsjfvd6vh0zhq2l4d6xgrma8l-shellcheck-0.10.0-man", "default": true }, { "name": "doc", - "path": "/nix/store/m7ym5mpdmy7xk22k92l4q83gy73pmb43-shellcheck-0.10.0-doc", + "path": "/nix/store/vn7d2fwlkjgq6hy3c7gjcypg3slkf592-shellcheck-0.10.0-doc", "default": true }, { "name": "out", - "path": "/nix/store/4pndxn9cdcpxh7ip9rxn4kl9z2gkaxqa-shellcheck-0.10.0" + "path": "/nix/store/dxqnpdj372kh001d84dg29l6l3aflrc0-shellcheck-0.10.0" } ], - "store_path": "/nix/store/01lx1jxzs82ka6xyxmsn2i59ii8x7mqz-shellcheck-0.10.0-bin" + "store_path": "/nix/store/kvhcnjzmjyqc641yd57f7g26nraw64sm-shellcheck-0.10.0-bin" }, "x86_64-darwin": { "outputs": [ { "name": "bin", - "path": "/nix/store/012s7j4i0db7z6iikbpgkh0ymz5snpng-shellcheck-0.10.0-bin", + "path": "/nix/store/ri8byd60sb58xqf3m0bli53xflx9n4l4-shellcheck-0.10.0-bin", "default": true }, { "name": "man", - "path": "/nix/store/rncrpamg4d8cfqrd1lsknnkm9v1dgqxz-shellcheck-0.10.0-man", + "path": "/nix/store/0an459l9ajzapm9kinqh344xnlzp70fy-shellcheck-0.10.0-man", "default": true }, { "name": "doc", - "path": "/nix/store/7y82z2xq5p47c2jcr6scl61j6pnkbqhn-shellcheck-0.10.0-doc", + "path": "/nix/store/b1hcrb9c98w7cwqjc5wy5rrfx1gnw7lz-shellcheck-0.10.0-doc", "default": true }, { "name": "out", - "path": "/nix/store/ff2gbs8ksqj8dxck7g8ay3fvar870zr5-shellcheck-0.10.0" + "path": "/nix/store/5rfsd78v2il52xqvxmx15pp52zlds4al-shellcheck-0.10.0" } ], - "store_path": "/nix/store/012s7j4i0db7z6iikbpgkh0ymz5snpng-shellcheck-0.10.0-bin" + "store_path": "/nix/store/ri8byd60sb58xqf3m0bli53xflx9n4l4-shellcheck-0.10.0-bin" }, "x86_64-linux": { "outputs": [ { "name": "bin", - "path": "/nix/store/c12rn8kf0w0wly8558lmr91avy1g4vi3-shellcheck-0.10.0-bin", + "path": "/nix/store/ayfrkdpk1sygzwwjqh19gcp5sfh557zd-shellcheck-0.10.0-bin", "default": true }, { "name": "man", - "path": "/nix/store/djgab9b1gd17pwp34f2iknpdkhj4y7fw-shellcheck-0.10.0-man", + "path": "/nix/store/n8asflghb73ph65f2ixvr8hv6h7v9w0g-shellcheck-0.10.0-man", "default": true }, { "name": "doc", - "path": "/nix/store/nvdwybbhwgan0jpp0k1krgnq25cvbjj9-shellcheck-0.10.0-doc", + "path": "/nix/store/wgb75fahwjf0h5gc7ww5zcvkhbm88sps-shellcheck-0.10.0-doc", "default": true }, { "name": "out", - "path": "/nix/store/qlyi42pbmfqa84jh8b6yhr3gijhflkdr-shellcheck-0.10.0" + "path": "/nix/store/vh0ng4iyxch4lqmjmkbbjx8dw8xp569y-shellcheck-0.10.0" } ], - "store_path": "/nix/store/c12rn8kf0w0wly8558lmr91avy1g4vi3-shellcheck-0.10.0-bin" + "store_path": "/nix/store/ayfrkdpk1sygzwwjqh19gcp5sfh557zd-shellcheck-0.10.0-bin" } } }, @@ -2120,8 +2120,8 @@ } }, "which@latest": { - "last_modified": "2025-07-28T17:09:23Z", - "resolved": "github:NixOS/nixpkgs/648f70160c03151bc2121d179291337ad6bc564b#which", + "last_modified": "2025-09-18T16:33:27Z", + "resolved": "github:NixOS/nixpkgs/f4b140d5b253f5e2a1ff4e5506edbf8267724bde#which", "source": "devbox-search", "version": "2.23", "systems": { @@ -2129,47 +2129,47 @@ "outputs": [ { "name": "out", - "path": "/nix/store/aj4kzwkawfknqp9h87nw82vhjwfmijmy-which-2.23", + "path": "/nix/store/m6ajvfdg2g30byc0c1zvgbqhmgf97nxa-which-2.23", "default": true } ], - "store_path": "/nix/store/aj4kzwkawfknqp9h87nw82vhjwfmijmy-which-2.23" + "store_path": "/nix/store/m6ajvfdg2g30byc0c1zvgbqhmgf97nxa-which-2.23" }, "aarch64-linux": { "outputs": [ { "name": "out", - "path": "/nix/store/x7dpk4xhkx57ad9bkfb7pdp869n2d1fg-which-2.23", + "path": "/nix/store/nnidy3hbb4kq6cv3dvb97lxbznbfb0zk-which-2.23", "default": true } ], - "store_path": "/nix/store/x7dpk4xhkx57ad9bkfb7pdp869n2d1fg-which-2.23" + "store_path": "/nix/store/nnidy3hbb4kq6cv3dvb97lxbznbfb0zk-which-2.23" }, "x86_64-darwin": { "outputs": [ { "name": "out", - "path": "/nix/store/jhz6w9rrbh6sdifkz9m1ywc311ndsjg4-which-2.23", + "path": "/nix/store/glwnjs1cfj0bs59swalr99i4hhdajjzk-which-2.23", "default": true } ], - "store_path": "/nix/store/jhz6w9rrbh6sdifkz9m1ywc311ndsjg4-which-2.23" + "store_path": "/nix/store/glwnjs1cfj0bs59swalr99i4hhdajjzk-which-2.23" }, "x86_64-linux": { "outputs": [ { "name": "out", - "path": "/nix/store/k44kjnci6lsjnr3migs25xflbvn651hm-which-2.23", + "path": "/nix/store/2kk8vjmh2d3fc8fzdzggxmdgyvwr4is8-which-2.23", "default": true } ], - "store_path": "/nix/store/k44kjnci6lsjnr3migs25xflbvn651hm-which-2.23" + "store_path": "/nix/store/2kk8vjmh2d3fc8fzdzggxmdgyvwr4is8-which-2.23" } } }, "xq-xml@1.3.0": { - "last_modified": "2025-07-28T17:09:23Z", - "resolved": "github:NixOS/nixpkgs/648f70160c03151bc2121d179291337ad6bc564b#xq-xml", + "last_modified": "2025-09-18T16:33:27Z", + "resolved": "github:NixOS/nixpkgs/f4b140d5b253f5e2a1ff4e5506edbf8267724bde#xq-xml", "source": "devbox-search", "version": "1.3.0", "systems": { @@ -2177,41 +2177,41 @@ "outputs": [ { "name": "out", - "path": "/nix/store/49hiicmg67z0gznpz3xa3gwhwjbrsha6-xq-1.3.0", + "path": "/nix/store/ynd5j6y99rxs146y6gylahpdbmyhlvb9-xq-1.3.0", "default": true } ], - "store_path": "/nix/store/49hiicmg67z0gznpz3xa3gwhwjbrsha6-xq-1.3.0" + "store_path": "/nix/store/ynd5j6y99rxs146y6gylahpdbmyhlvb9-xq-1.3.0" }, "aarch64-linux": { "outputs": [ { "name": "out", - "path": "/nix/store/2zmfgjs4bs760szpdl8rdfd72rsfwf69-xq-1.3.0", + "path": "/nix/store/lpnfai5g62f9migbdcfj33ss6z1cdgw9-xq-1.3.0", "default": true } ], - "store_path": "/nix/store/2zmfgjs4bs760szpdl8rdfd72rsfwf69-xq-1.3.0" + "store_path": "/nix/store/lpnfai5g62f9migbdcfj33ss6z1cdgw9-xq-1.3.0" }, "x86_64-darwin": { "outputs": [ { "name": "out", - "path": "/nix/store/s9p6xqx06zkhspc8va7dqdq2jnzbvd3b-xq-1.3.0", + "path": "/nix/store/rrl5y0aamf0wq85kb65wyhr0h9qp12pi-xq-1.3.0", "default": true } ], - "store_path": "/nix/store/s9p6xqx06zkhspc8va7dqdq2jnzbvd3b-xq-1.3.0" + "store_path": "/nix/store/rrl5y0aamf0wq85kb65wyhr0h9qp12pi-xq-1.3.0" }, "x86_64-linux": { "outputs": [ { "name": "out", - "path": "/nix/store/7pk6bxd9k270bjaiypkknp6lkxd78gqz-xq-1.3.0", + "path": "/nix/store/3dvhqvkw8zfwilyxnkjw5d8py1l2x9xz-xq-1.3.0", "default": true } ], - "store_path": "/nix/store/7pk6bxd9k270bjaiypkknp6lkxd78gqz-xq-1.3.0" + "store_path": "/nix/store/3dvhqvkw8zfwilyxnkjw5d8py1l2x9xz-xq-1.3.0" } } }, diff --git a/nix/flake.lock b/nix/flake.lock index 40e262096f..b0e9ff3f3f 100644 --- a/nix/flake.lock +++ b/nix/flake.lock @@ -2,11 +2,11 @@ "nodes": { "nixpkgs": { "locked": { - "lastModified": 1757745802, - "narHash": "sha256-hLEO2TPj55KcUFUU1vgtHE9UEIOjRcH/4QbmfHNF820=", + "lastModified": 1760284886, + "narHash": "sha256-TK9Kr0BYBQ/1P5kAsnNQhmWWKgmZXwUQr4ZMjCzWf2c=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "c23193b943c6c689d70ee98ce3128239ed9e32d1", + "rev": "cf3f5c4def3c7b5f1fc012b3d839575dbe552d43", "type": "github" }, "original": { From 28327704f95de0100aa31414a304c0c3eeb4f086 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Weisbarth?= Date: Tue, 14 Oct 2025 11:33:09 +0200 Subject: [PATCH 13/20] Remove changes to use them again in PR #3954 --- src/autoscaler/models/app.go | 87 +----------------------------------- 1 file changed, 1 insertion(+), 86 deletions(-) diff --git a/src/autoscaler/models/app.go b/src/autoscaler/models/app.go index 8ebfa5a4c7..af145ab125 100644 --- a/src/autoscaler/models/app.go +++ b/src/autoscaler/models/app.go @@ -1,13 +1,6 @@ package models -import ( - "encoding/json" - "errors" - "fmt" - "os" - "regexp" - "time" -) +import "time" type ScalingType int type ScalingStatus int @@ -52,81 +45,3 @@ type AppScalingResult struct { Adjustment int `json:"adjustment"` CooldownExpiredAt int64 `json:"cool_down_expired_at"` } - -// 🚧 To-do: Bring this in line with the content of “models/common_typges.go”. -// ================================================================================ -// GUIDs -// ================================================================================ - -// Globally unique identifier in the context of a “Cloud Foundry” installation; -type CfGuid string - -func (g CfGuid) String() string { - return string(g) -} - -type CfGuidParser struct { - regexp *regexp.Regexp -} - -func NewCfGuidParser() CfGuidParser { - filePath := "../../../schema/json/shared_definitions.json" - jsonData, err := os.ReadFile(filePath) - if err != nil { - errMsg := fmt.Errorf("could not read file \"%s\"\nError: %w", filePath, err) - // Panicing here is O.K. because it does not make sense to launch autoscaler because it has - // been shipped with an invalid (or non-existent) file that should contain a json-schema. - panic(fmt.Sprintf( - "%s\nThis is a programming-error as the file must be on the hardcoded location.", - errMsg)) - } - - // Unfortunately there is no ordinary library comparable to - // e.g. that allows to parse arbitrary JSON without - // defining homomorphic structs in the host-language. So here comes a type that describes the - // structure of the file `…/shared_definitions.json` (see above) with the sole intention to read - // out the content of the field `pattern`. - type Schema struct { - Schemas struct { - Guid struct { - Pattern string `json:"pattern"` - } `json:"guid"` - } `json:"schemas"` - } - var schema Schema - err = json.Unmarshal(jsonData, &schema) - if err != nil { - errMsg := fmt.Errorf("could not unmarshal JSON from file \"%s\"\nError: %w", filePath, err) - // Panicing here is O.K. because it does not make sense to launch autoscaler because it has - // been shipped with an file with invalid json-code. - panic(fmt.Sprintf( - "%s\nThis is a programming-error as the local Schema-struct must match roughly the file-structure.", - errMsg)) - } - pattern := schema.Schemas.Guid.Pattern - - r, err := regexp.CompilePOSIX(pattern) - if err != nil { - // Panicing here is O.K. because it does not make sense to launch autoscaler because it has - // been shipped with an invalid json-schema. - panic(`The provided pattern is invalid. -This is a programming-error as the pattern must be a valid POSIX-regexp.`) - } - - return CfGuidParser{regexp: r} -} - -func (p CfGuidParser) Parse(rawGuid string) (CfGuid, error) { - matched := p.regexp.MatchString(rawGuid) - if !matched { - msg := fmt.Sprintf("The provided string does not look like a Cloud Foundry GUID: %s", rawGuid) - return "", errors.New(msg) - } - - return CfGuid(rawGuid), nil -} - -func ParseGuid(rawGuid string) (CfGuid, error) { - p := NewCfGuidParser() - return p.Parse(rawGuid) -} From cb8652fce7db9ecc548a57dfda3d08ae69806b01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Weisbarth?= Date: Tue, 14 Oct 2025 16:30:03 +0200 Subject: [PATCH 14/20] Allow additional attributes for backwards-compatibility; --- schema/json/scaling-policy.legacy-schema.json | 2 +- .../api/policyvalidator/policy_validator_test.go | 8 +++++++- .../api/policyvalidator/scaling-policy.legacy-schema.json | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/schema/json/scaling-policy.legacy-schema.json b/schema/json/scaling-policy.legacy-schema.json index 67d6a7e6ff..06f64a2c54 100644 --- a/schema/json/scaling-policy.legacy-schema.json +++ b/schema/json/scaling-policy.legacy-schema.json @@ -926,5 +926,5 @@ ] } ], - "additionalProperties": false + "additionalProperties": true } diff --git a/src/autoscaler/api/policyvalidator/policy_validator_test.go b/src/autoscaler/api/policyvalidator/policy_validator_test.go index acc7de580d..6ec868444d 100644 --- a/src/autoscaler/api/policyvalidator/policy_validator_test.go +++ b/src/autoscaler/api/policyvalidator/policy_validator_test.go @@ -225,6 +225,9 @@ var _ = Describe("PolicyValidator", func() { // This needs to be passed for backwards-compatibility. We allowed in former times to set // this parameter `stats_window_secs` via configuration. We must silently ignore this // parameter today. + // + // In general we silently ignore every parameter that is used but unknown. In the future we + // want to change this. Context("when legacy-fields are present", func() { BeforeEach(func() { policyString = `{ @@ -239,7 +242,10 @@ var _ = Describe("PolicyValidator", func() { "operator":">=", "cool_down_secs":300, "adjustment":"+1" - }] + }], + "is_admin": true, + "is_sso": true, + "role": "admin" }` }) It("the validation succeed and remove them", func() { diff --git a/src/autoscaler/api/policyvalidator/scaling-policy.legacy-schema.json b/src/autoscaler/api/policyvalidator/scaling-policy.legacy-schema.json index 67d6a7e6ff..06f64a2c54 100644 --- a/src/autoscaler/api/policyvalidator/scaling-policy.legacy-schema.json +++ b/src/autoscaler/api/policyvalidator/scaling-policy.legacy-schema.json @@ -926,5 +926,5 @@ ] } ], - "additionalProperties": false + "additionalProperties": true } From e35829b6649aea1d18ae7c95af0a9487edb7e822 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Weisbarth?= Date: Tue, 14 Oct 2025 17:24:19 +0200 Subject: [PATCH 15/20] Adapt acceptance-tests to new schema. --- src/acceptance/api/api_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/acceptance/api/api_test.go b/src/acceptance/api/api_test.go index 90b888af8e..37c77fc468 100644 --- a/src/acceptance/api/api_test.go +++ b/src/acceptance/api/api_test.go @@ -115,13 +115,13 @@ var _ = Describe("AutoScaler Public API", func() { It("should fail to create an invalid custom metrics submission", func() { By("creating custom metrics submission with invalid string") response, status := createPolicy(GenerateBindingsWithScalingPolicy("invalid-value", 1, 2, "memoryused", 30, 100)) - Expect(string(response)).Should(MatchJSON(`[{"context":"(root).configuration.custom_metrics.metric_submission_strategy.allow_from","description":"configuration.custom_metrics.metric_submission_strategy.allow_from must be one of the following: \"bound_app\""}]`)) + Expect(string(response)).Should(MatchJSON(`[{"context":"(root).configuration.custom_metrics.metric_submission_strategy.allow_from","description":"configuration.custom_metrics.metric_submission_strategy.allow_from must be one of the following: \"bound_app\", \"same_app\""}]`)) Expect(status).To(Equal(400)) By("creating custom metrics submission with empty value ' '") policy := GenerateBindingsWithScalingPolicy("", 1, 2, "memoryused", 30, 100) newPolicy, status := createPolicy(policy) - Expect(string(newPolicy)).Should(MatchJSON(`[{"context":"(root).configuration.custom_metrics.metric_submission_strategy.allow_from","description":"configuration.custom_metrics.metric_submission_strategy.allow_from must be one of the following: \"bound_app\""}]`)) + Expect(string(newPolicy)).Should(MatchJSON(`[{"context":"(root).configuration.custom_metrics.metric_submission_strategy.allow_from","description":"configuration.custom_metrics.metric_submission_strategy.allow_from must be one of the following: \"bound_app\", \"same_app\""}]`)) Expect(status).To(Equal(400)) }) @@ -277,7 +277,7 @@ var _ = Describe("AutoScaler Public API", func() { It("should fail to update an invalid custom metrics strategy", func() { expectedPolicy = GenerateBindingsWithScalingPolicy("invalid-update", 1, 2, "memoryused", 30, 100) actualPolicy, status = createPolicy(expectedPolicy) - Expect(string(actualPolicy)).Should(MatchJSON(`[{"context":"(root).configuration.custom_metrics.metric_submission_strategy.allow_from","description":"configuration.custom_metrics.metric_submission_strategy.allow_from must be one of the following: \"bound_app\""}]`)) + Expect(string(actualPolicy)).Should(MatchJSON(`[{"context":"(root).configuration.custom_metrics.metric_submission_strategy.allow_from","description":"configuration.custom_metrics.metric_submission_strategy.allow_from must be one of the following: \"bound_app\", \"same_app\""}]`)) Expect(status).To(Equal(400)) }) It("should succeed to update a valid custom metrics strategy", func() { From 97b73683bf5426145c8beaf7dd956647d4a0f227 Mon Sep 17 00:00:00 2001 From: joergdw Date: Tue, 21 Oct 2025 10:40:23 +0200 Subject: [PATCH 16/20] Apply suggestions from code review Co-authored-by: Silvestre Zabala --- schema/json/policy-configuration.legacy-schema.json | 2 +- src/autoscaler/api/publicapiserver/public_api_handler_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/schema/json/policy-configuration.legacy-schema.json b/schema/json/policy-configuration.legacy-schema.json index ff06aec9b8..6e163a0e0e 100644 --- a/schema/json/policy-configuration.legacy-schema.json +++ b/schema/json/policy-configuration.legacy-schema.json @@ -1,7 +1,7 @@ { "$schema": "http://json-schema.org/draft-05/schema#", "title": "", - "description": "Schema for a scaling-policy.", + "description": "Schema for the configuration options of scaling policy.", "type": "object", "properties": { diff --git a/src/autoscaler/api/publicapiserver/public_api_handler_test.go b/src/autoscaler/api/publicapiserver/public_api_handler_test.go index 75439b5bf6..d12e82097e 100644 --- a/src/autoscaler/api/publicapiserver/public_api_handler_test.go +++ b/src/autoscaler/api/publicapiserver/public_api_handler_test.go @@ -94,7 +94,7 @@ var _ = Describe("PublicApiHandler", func() { }] }, "is_admin": true - }` // 🚧 To-do: ValidPolicyStrWithExtraFields is still not used in any test. + }` InvalidCustomMetricsConfigurationStr = `{ "configuration": { "custom_metrics": { From 0121d84fb7e537d5913b23573970791aed65d267 Mon Sep 17 00:00:00 2001 From: joergdw Date: Tue, 21 Oct 2025 10:41:40 +0200 Subject: [PATCH 17/20] Apply suggestions from code review Co-authored-by: Silvestre Zabala --- schema/json/policy-configuration.legacy-schema.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schema/json/policy-configuration.legacy-schema.json b/schema/json/policy-configuration.legacy-schema.json index 6e163a0e0e..7362d63d4e 100644 --- a/schema/json/policy-configuration.legacy-schema.json +++ b/schema/json/policy-configuration.legacy-schema.json @@ -1,6 +1,6 @@ { "$schema": "http://json-schema.org/draft-05/schema#", - "title": "", + "title": "Autoscaler Scaling Policy Configuration Schema", "description": "Schema for the configuration options of scaling policy.", "type": "object", From 1709358a276edc167436d59843179c0b58443745 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Weisbarth?= Date: Tue, 21 Oct 2025 10:40:52 +0200 Subject: [PATCH 18/20] Bring back old test for additional attributes; --- .../public_api_handler_test.go | 23 +++++++++---------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/autoscaler/api/publicapiserver/public_api_handler_test.go b/src/autoscaler/api/publicapiserver/public_api_handler_test.go index d12e82097e..93f01931b7 100644 --- a/src/autoscaler/api/publicapiserver/public_api_handler_test.go +++ b/src/autoscaler/api/publicapiserver/public_api_handler_test.go @@ -381,18 +381,17 @@ var _ = Describe("PublicApiHandler", func() { }) }) - // // 🚧🧐 To-do for the reviewer: Check if we can just ommit this test. - // When("providing extra fields", func() { - // BeforeEach(func() { - // pathVariables["appId"] = TEST_APP_ID - // req, _ = http.NewRequest(http.MethodPut, "", bytes.NewBufferString(ValidPolicyStrWithExtraFields)) - // schedulerStatus = 200 - // }) - // It("should succeed and ignore the extra fields", func() { - // Expect(resp.Code).To(Equal(http.StatusOK)) - // Expect(resp.Body).To(MatchJSON(ValidPolicyStr)) - // }) - // }) + When("providing extra fields", func() { + BeforeEach(func() { + pathVariables["appId"] = TEST_APP_ID + req, _ = http.NewRequest(http.MethodPut, "", bytes.NewBufferString(ValidPolicyStrWithExtraFields)) + schedulerStatus = 200 + }) + It("should succeed and ignore the extra fields", func() { + Expect(resp.Code).To(Equal(http.StatusOK)) + Expect(resp.Body).To(MatchJSON(ValidPolicyStr)) + }) + }) When("scheduler returns 204 status code", func() { BeforeEach(func() { From 8178d7d88d060fbfb8df0ab4164e614a3ac50997 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Weisbarth?= Date: Tue, 21 Oct 2025 11:36:17 +0200 Subject: [PATCH 19/20] Rename files according to review-finding; --- jobs/golangapiserver/templates/apiserver.yml.erb | 2 +- ...on.legacy-schema.json => policy-configuration.schema.json} | 0 ...g-policy.legacy-schema.json => scaling-policy.schema.json} | 2 +- src/autoscaler/api/broker/broker_suite_test.go | 2 +- src/autoscaler/api/brokerserver/broker_server_suite_test.go | 2 +- src/autoscaler/api/cmd/api/api_suite_test.go | 2 +- src/autoscaler/api/default_config.json | 2 +- ...on.legacy-schema.json => policy-configuration.schema.json} | 4 ++-- src/autoscaler/api/policyvalidator/policy_validator_test.go | 2 +- ...g-policy.legacy-schema.json => scaling-policy.schema.json} | 2 +- .../api/publicapiserver/publicapiserver_suite_test.go | 2 +- src/autoscaler/integration/components_test.go | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) rename schema/json/{policy-configuration.legacy-schema.json => policy-configuration.schema.json} (100%) rename schema/json/{scaling-policy.legacy-schema.json => scaling-policy.schema.json} (99%) rename src/autoscaler/api/policyvalidator/{policy-configuration.legacy-schema.json => policy-configuration.schema.json} (85%) rename src/autoscaler/api/policyvalidator/{scaling-policy.legacy-schema.json => scaling-policy.schema.json} (99%) diff --git a/jobs/golangapiserver/templates/apiserver.yml.erb b/jobs/golangapiserver/templates/apiserver.yml.erb index 27f67f564d..b7cc80e4c0 100644 --- a/jobs/golangapiserver/templates/apiserver.yml.erb +++ b/jobs/golangapiserver/templates/apiserver.yml.erb @@ -86,7 +86,7 @@ broker_credentials: catalog_path: /var/vcap/jobs/golangapiserver/config/catalog.json catalog_schema_path: /var/vcap/packages/golangapiserver/catalog.schema.json info_file_path: /var/vcap/jobs/golangapiserver/config/info.json -policy_schema_path: /var/vcap/packages/golangapiserver/scaling-policy.legacy-schema.json +policy_schema_path: /var/vcap/packages/golangapiserver/scaling-policy.schema.json dashboard_redirect_uri: <%= p("autoscaler.apiserver.broker.server.dashboard_redirect_uri") %> default_credential_type: <%= p("autoscaler.apiserver.broker.default_credential_type") %> diff --git a/schema/json/policy-configuration.legacy-schema.json b/schema/json/policy-configuration.schema.json similarity index 100% rename from schema/json/policy-configuration.legacy-schema.json rename to schema/json/policy-configuration.schema.json diff --git a/schema/json/scaling-policy.legacy-schema.json b/schema/json/scaling-policy.schema.json similarity index 99% rename from schema/json/scaling-policy.legacy-schema.json rename to schema/json/scaling-policy.schema.json index 06f64a2c54..e8573ca326 100644 --- a/schema/json/scaling-policy.legacy-schema.json +++ b/schema/json/scaling-policy.schema.json @@ -18,7 +18,7 @@ ] }, "configuration": { - "$ref": "./policy-configuration.legacy-schema.json" + "$ref": "./policy-configuration.schema.json" }, "instance_min_count": { "$id": "#/properties/instance_min_count", diff --git a/src/autoscaler/api/broker/broker_suite_test.go b/src/autoscaler/api/broker/broker_suite_test.go index bcd7df9a06..707888fa2b 100644 --- a/src/autoscaler/api/broker/broker_suite_test.go +++ b/src/autoscaler/api/broker/broker_suite_test.go @@ -50,7 +50,7 @@ var _ = BeforeSuite(func() { conf = &config.Config{ CatalogPath: "../exampleconfig/catalog-example.json", DashboardRedirectURI: dashBoardURL, - PolicySchemaPath: "../policyvalidator/scaling-policy.legacy-schema.json", + PolicySchemaPath: "../policyvalidator/scaling-policy.schema.json", DefaultCustomMetricsCredentialType: "binding-secret", } diff --git a/src/autoscaler/api/brokerserver/broker_server_suite_test.go b/src/autoscaler/api/brokerserver/broker_server_suite_test.go index 7ac32f5c1c..98ef89b1f8 100644 --- a/src/autoscaler/api/brokerserver/broker_server_suite_test.go +++ b/src/autoscaler/api/brokerserver/broker_server_suite_test.go @@ -129,7 +129,7 @@ var _ = BeforeSuite(func() { }, CatalogPath: "../exampleconfig/catalog-example.json", CatalogSchemaPath: "../schemas/catalog.schema.json", - PolicySchemaPath: "../policyvalidator/scaling-policy.legacy-schema.json", + PolicySchemaPath: "../policyvalidator/scaling-policy.schema.json", Scheduler: config.SchedulerConfig{ SchedulerURL: schedulerServer.URL(), }, diff --git a/src/autoscaler/api/cmd/api/api_suite_test.go b/src/autoscaler/api/cmd/api/api_suite_test.go index c9b2cd9bd5..296f3af8c0 100644 --- a/src/autoscaler/api/cmd/api/api_suite_test.go +++ b/src/autoscaler/api/cmd/api/api_suite_test.go @@ -164,7 +164,7 @@ var _ = SynchronizedBeforeSuite(func() []byte { conf.CatalogPath = "../../exampleconfig/catalog-example.json" conf.CatalogSchemaPath = "../../schemas/catalog.schema.json" - conf.PolicySchemaPath = "../policyvalidator/scaling-policy.legacy-schema.json" + conf.PolicySchemaPath = "../policyvalidator/scaling-policy.schema.json" schedulerServer = ghttp.NewServer() conf.Scheduler.SchedulerURL = schedulerServer.URL() diff --git a/src/autoscaler/api/default_config.json b/src/autoscaler/api/default_config.json index f41d9b021e..9a3f75fce5 100644 --- a/src/autoscaler/api/default_config.json +++ b/src/autoscaler/api/default_config.json @@ -9,7 +9,7 @@ }, "catalog_schema_path": "/home/vcap/app/api/schemas/catalog.schema.json", "info_file_path": "/home/vcap/app/api/default_info.json", - "policy_schema_path": "/home/vcap/app/api/policyvalidator/scaling-policy.legacy-schema.json", + "policy_schema_path": "/home/vcap/app/api/policyvalidator/scaling-policy.schema.json", "dashboard_redirect_uri": null, "default_credential_type": "binding-secret", "health": { diff --git a/src/autoscaler/api/policyvalidator/policy-configuration.legacy-schema.json b/src/autoscaler/api/policyvalidator/policy-configuration.schema.json similarity index 85% rename from src/autoscaler/api/policyvalidator/policy-configuration.legacy-schema.json rename to src/autoscaler/api/policyvalidator/policy-configuration.schema.json index ff06aec9b8..7362d63d4e 100644 --- a/src/autoscaler/api/policyvalidator/policy-configuration.legacy-schema.json +++ b/src/autoscaler/api/policyvalidator/policy-configuration.schema.json @@ -1,7 +1,7 @@ { "$schema": "http://json-schema.org/draft-05/schema#", - "title": "", - "description": "Schema for a scaling-policy.", + "title": "Autoscaler Scaling Policy Configuration Schema", + "description": "Schema for the configuration options of scaling policy.", "type": "object", "properties": { diff --git a/src/autoscaler/api/policyvalidator/policy_validator_test.go b/src/autoscaler/api/policyvalidator/policy_validator_test.go index 6ec868444d..983dd92591 100644 --- a/src/autoscaler/api/policyvalidator/policy_validator_test.go +++ b/src/autoscaler/api/policyvalidator/policy_validator_test.go @@ -48,7 +48,7 @@ var _ = Describe("PolicyValidator", func() { upperDiskThreshold = 2 * 1024 policyValidator = NewPolicyValidator( - "./scaling-policy.legacy-schema.json", + "./scaling-policy.schema.json", lowerCPUThreshold, upperCPUThreshold, lowerCPUUtilThreshold, diff --git a/src/autoscaler/api/policyvalidator/scaling-policy.legacy-schema.json b/src/autoscaler/api/policyvalidator/scaling-policy.schema.json similarity index 99% rename from src/autoscaler/api/policyvalidator/scaling-policy.legacy-schema.json rename to src/autoscaler/api/policyvalidator/scaling-policy.schema.json index 06f64a2c54..e8573ca326 100644 --- a/src/autoscaler/api/policyvalidator/scaling-policy.legacy-schema.json +++ b/src/autoscaler/api/policyvalidator/scaling-policy.schema.json @@ -18,7 +18,7 @@ ] }, "configuration": { - "$ref": "./policy-configuration.legacy-schema.json" + "$ref": "./policy-configuration.schema.json" }, "instance_min_count": { "$id": "#/properties/instance_min_count", diff --git a/src/autoscaler/api/publicapiserver/publicapiserver_suite_test.go b/src/autoscaler/api/publicapiserver/publicapiserver_suite_test.go index 3c759d17e7..893834ab1e 100644 --- a/src/autoscaler/api/publicapiserver/publicapiserver_suite_test.go +++ b/src/autoscaler/api/publicapiserver/publicapiserver_suite_test.go @@ -104,7 +104,7 @@ var _ = BeforeSuite(func() { CFServer: helpers.ServerConfig{ Port: 14000 + GinkgoParallelProcess(), }, - PolicySchemaPath: "../policyvalidator/scaling-policy.legacy-schema.json", + PolicySchemaPath: "../policyvalidator/scaling-policy.schema.json", Scheduler: config.SchedulerConfig{ SchedulerURL: schedulerServer.URL(), }, diff --git a/src/autoscaler/integration/components_test.go b/src/autoscaler/integration/components_test.go index a36ad17fb5..3e2ee356da 100644 --- a/src/autoscaler/integration/components_test.go +++ b/src/autoscaler/integration/components_test.go @@ -232,7 +232,7 @@ func DefaultGolangAPITestConfig() apiConfig.Config { }, CatalogPath: "../servicebroker/config/catalog.json", CatalogSchemaPath: "../api/schemas/catalog.schema.json", - PolicySchemaPath: "../api/policyvalidator/scaling-policy.legacy-schema.json", + PolicySchemaPath: "../api/policyvalidator/scaling-policy.schema.json", InfoFilePath: "../api/exampleconfig/catalog-example.json", DashboardRedirectURI: "", CF: cf.Config{ From d3b0803d4512e26327e8fa87cbb639993d9f28bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Weisbarth?= Date: Tue, 21 Oct 2025 15:29:51 +0200 Subject: [PATCH 20/20] Use again latest stemcell; --- templates/app-autoscaler.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/app-autoscaler.yml b/templates/app-autoscaler.yml index e42d207ba4..d6d51eea07 100644 --- a/templates/app-autoscaler.yml +++ b/templates/app-autoscaler.yml @@ -125,7 +125,7 @@ addons: stemcells: - alias: default os: ubuntu-jammy - version: "1.915" # 🚧 To-do: Use "latest" again after successfully passing all tests; + version: "latest" instance_groups: # Postgres Instance Group