diff --git a/examples/chainfleetautoscaler.yaml b/examples/chainfleetautoscaler.yaml index f0cff7d553..4ff3f918f1 100644 --- a/examples/chainfleetautoscaler.yaml +++ b/examples/chainfleetautoscaler.yaml @@ -16,7 +16,7 @@ # # [Stage:Dev] # [FeatureFlag:ScheduledAutoscaler] -# Example of a FleetAutoscaler - this is used to scale a Fleet based on a schedule. +# Example of a FleetAutoscaler - this is used to scale a Fleet based on a chain. # # @@ -27,65 +27,73 @@ kind: FleetAutoscaler metadata: name: chain-fleet-autoscaler spec: + fleetName: fleet-example policy: # Chain based policy for autoscaling. type: Chain chain: # Id of chain entry. If not set, the Id will be defaulted to the index of the entry within the chain. - id: "weekday" - type: Schedule # Schedule based condition. + type: Schedule # Schedule based policy. schedule: between: - # The policy becomes eligible for application starting on Feb 20, 2024 at 4:04 PM EST. If not set, the policy will immediately be eligible for application. - start: "2024-02-20T16:04:04-05:00" - # The policy becomes ineligible for application on Feb 23, 2024 at 4:04 PM EST. If not set, the policy will always be eligible for application (after the start time). - end: "2024-02-23T16:04:04-05:00" + # The policy becomes eligible for application starting on Feb 20, 2100 at 4:04 PM EST. If not set, the policy will immediately be eligible for application. + start: "2100-02-20T16:04:04-05:00" + # The policy becomes ineligible for application on Feb 23, 2100 at 4:04 PM EST. If not set, the policy will always be eligible for application (after the start time). + end: "2100-02-23T16:04:04-05:00" activePeriod: # Timezone to be used for the startCron field. Defaults to UTC if not set. timezone: "America/New_York" # Start applying the policy everyday at 1:00 AM EST. If not set, the policy will always be applied in the .between window. - # (Only eligible starting on Feb 20, 2024 at 4:04 PM). + # (Only eligible starting on Feb 20, 2100 at 4:04 PM). startCron: "0 1 * * 0" # Only apply the policy for 5 hours. If not set, the duration will be defaulted to always/indefinite. duration: "5h" - # Policy to be applied during the activePeriod. Required. - policy: - type: Buffer - buffer: - bufferSize: 50 - minReplicas: 100 - maxReplicas: 2000 + # Policy to be applied during the activePeriod. Required. + policy: + type: Buffer + buffer: + bufferSize: 50 + minReplicas: 100 + maxReplicas: 2000 # Id of chain entry. If not set, the Id will be defaulted to the index of the entry within the chain list. - id: "weekend" - type: Schedule + type: Schedule # Schedule based policy. schedule: between: - # The policy becomes eligible for application starting on Feb 24, 2024 at 4:05 PM EST. If not set, the policy will immediately be eligible for application. - start: "2024-02-24T16:04:05-05:00" - # The policy becomes ineligible for application starting on Feb 26, 2024 at 4:05 PM EST. If not set, the policy will always be eligible for application (after the start time). - end: "2024-02-26T16:04:05-05:00" + # The policy becomes eligible for application starting on Feb 24, 2100 at 4:05 PM EST. If not set, the policy will immediately be eligible for application. + start: "2100-02-24T16:04:05-05:00" + # The policy becomes ineligible for application starting on Feb 26, 2100 at 4:05 PM EST. If not set, the policy will always be eligible for application (after the start time). + end: "2100-02-26T16:04:05-05:00" activePeriod: # Timezone to be used for the startCron field. Defaults to UTC if not set. timezone: "America/New_York" # Start applying the policy everyday at 1:00 AM EST. If not set, the policy will always be applied in the .between window. - # (Only eligible starting on Feb 24, 2024 at 4:05 PM EST) + # (Only eligible starting on Feb 24, 2100 at 4:05 PM EST) startCron: "0 1 * * 0" # Only apply the policy for 7 hours. If not set the duration will be defaulted to always/indefinite. duration: "7h" - # Policy to be applied during the activePeriod. Required. - policy: - type: Counter - counter: - key: rooms - bufferSize: 10 - minCapacity: 500 - maxCapacity: 1000 + # Policy to be applied during the activePeriod. Required. + policy: + type: Counter + counter: + key: rooms + bufferSize: 10 + minCapacity: 500 + maxCapacity: 1000 # Id of chain entry. If not set, the Id will be defaulted to the index of the entry within the chain list. - id: "default" # Policy will always be applied when no other policy is applicable. Required. - policy: - type: Buffer - buffer: - bufferSize: 5 - minReplicas: 100 - maxReplicas: 2000 + type: Buffer + buffer: + bufferSize: 5 + minReplicas: 100 + maxReplicas: 2000 + # The autoscaling sync strategy, this will determine how frequent any schedules within the chain is evaluated. + sync: + # type of the sync. for now, only FixedInterval is available + type: FixedInterval + # parameters of the fixedInterval sync + fixedInterval: + # the time in seconds between each auto scaling + seconds: 30 diff --git a/examples/schedulefleetautoscaler.yaml b/examples/schedulefleetautoscaler.yaml new file mode 100644 index 0000000000..55e3410f9e --- /dev/null +++ b/examples/schedulefleetautoscaler.yaml @@ -0,0 +1,62 @@ +--- +# Copyright 2024 Google LLC All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# +# [Stage:Dev] +# [FeatureFlag:ScheduledAutoscaler] +# Example of a FleetAutoscaler - this is used to scale a Fleet based on a schedule. +# + +# +# For a full reference and details: https://agones.dev/site/docs/reference/fleetautoscaler/ +# +apiVersion: autoscaling.agones.dev/v1 +kind: FleetAutoscaler +metadata: + name: schedule-fleet-autoscaler +spec: + fleetName: fleet-example + policy: + # Schedule based policy for autoscaling. + type: Schedule + schedule: + between: + # The policy becomes eligible for application starting on July 4th, 2024 at 4:04 PM PST. If not set, the policy will immediately be eligible for application. + start: "2024-07-04T16:04:04-07:00" + # The policy becomes ineligible for application on Sept 21, 2100 at 4:04 PM PST. If not set, the policy will always be eligible for application (after the start time). + end: "2100-09-21T16:04:04-07:00" + activePeriod: + # Timezone to be used for the startCron field. Defaults to UTC if not set. + timezone: "America/Los_Angeles" + # Start applying the policy everyday at 1:00 AM PST. If not set, the policy will always be applied in the .between window. + # (Only eligible starting on Feb 20, 2100 at 4:04 PM). + startCron: "0 1 * * 0" + # Only apply the policy for 5 hours. If not set, the duration will be defaulted to always/indefinite. + duration: "5h" + # Policy to be applied during the activePeriod. Required. + policy: + type: Buffer + buffer: + bufferSize: 50 + minReplicas: 100 + maxReplicas: 2000 + # The autoscaling sync strategy, this will determine how frequent the schedule is evaluated. + sync: + # type of the sync. for now, only FixedInterval is available + type: FixedInterval + # parameters of the fixedInterval sync + fixedInterval: + # the time in seconds between each auto scaling + seconds: 30 diff --git a/go.mod b/go.mod index bc3f239596..aa0a4763f0 100644 --- a/go.mod +++ b/go.mod @@ -23,6 +23,7 @@ require ( github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.16.0 + github.com/robfig/cron/v3 v3.0.1 github.com/sirupsen/logrus v1.9.0 github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.7.0 diff --git a/go.sum b/go.sum index 514371bce4..b93bd0a7b3 100644 --- a/go.sum +++ b/go.sum @@ -381,6 +381,8 @@ github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7z github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+PymziUAg= github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= +github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= diff --git a/install/helm/agones/templates/crds/_fleetautoscalerpolicy.yaml b/install/helm/agones/templates/crds/_fleetautoscalerpolicy.yaml index f28534aa40..0bf303f374 100644 --- a/install/helm/agones/templates/crds/_fleetautoscalerpolicy.yaml +++ b/install/helm/agones/templates/crds/_fleetautoscalerpolicy.yaml @@ -15,11 +15,13 @@ --- {{/* schema for a fleet autoscaler policy */}} {{- define "fleetautoscaler.policy" }} +{{- if .includePolicy }} policy: type: object required: - type properties: +{{- end }} type: type: string enum: @@ -27,6 +29,9 @@ policy: - Webhook - Counter - List + {{- if .includeSchedulePolicy }} + - Schedule + {{- end }} {{- if .includeChainPolicy }} - Chain {{- end }} @@ -112,6 +117,33 @@ policy: anyOf: - type: integer - type: string + {{- if .includeSchedulePolicy }} + schedule: # Defines when the policy is applied. + type: object + nullable: true + required: + - policy + properties: + between: + type: object + nullable: true + properties: + start: # Defines when to start evaluating the active period, must conform to RFC3339. + type: string + end: # Defines when to stop evaluating the active period, must conform to RFC3339. + type: string + activePeriod: + type: object + nullable: true + properties: + timezone: # Timezone to be used for the startCron field, must conform with the IANA Time Zone database (e.g. America/New_York). + type: string + startCron: # Cron expression defining when to start applying the policy. All TZ/CRON_TZ specification within startCron will be rejected, please use the timezone field above to specify a timezone. Must conform with UNIX CRON syntax. + type: string + duration: # The length of time the policy should be applied for (e.g. 2h45m). + type: string + {{- include "fleetautoscaler.policy" (dict "includeChainPolicy" false "includeSchedulePolicy" false "includePolicy" true) | indent 8 }} + {{- end }} {{- if .includeChainPolicy }} chain: type: array @@ -120,27 +152,10 @@ policy: type: object nullable: true required: - - policy + - type properties: id: # The Id of a chain entry. type: string - schedule: # Defines when the policy is applied. - type: object - properties: - between: - type: object - start: # Defines when to start evaluating the active period, must conform to RFC3339. - type: string - end: # Defines when to stop evaluating the active period, must conform to RFC3339. - type: string - activePeriod: - type: object - timezone: # Timezone to be used for the startCron field, must conform with the IANA Time Zone database (e.g. America/New_York). - type: string - startCron: # Cron expression defining when to start applying the policy. All TZ/CRON_TZ specification within startCron will be rejected, please use the timezone field above to specify a timezone. Must conform with UNIX CRON syntax. - type: string - duration: # The length of time the policy should be applied for (e.g. 2h45m). - type: string - {{- include "fleetautoscaler.policy" (dict "includeChainPolicy" false) | indent 12 }} # Defines which policy to apply during the active period. Required. + {{- include "fleetautoscaler.policy" (dict "includeChainPolicy" false "includeSchedulePolicy" true "includePolicy" false) | indent 6 }} # Defines which policy to apply during the active period. Required. {{- end }} {{- end }} diff --git a/install/helm/agones/templates/crds/fleetautoscaler.yaml b/install/helm/agones/templates/crds/fleetautoscaler.yaml index 8e046b1df9..071d705725 100644 --- a/install/helm/agones/templates/crds/fleetautoscaler.yaml +++ b/install/helm/agones/templates/crds/fleetautoscaler.yaml @@ -56,7 +56,7 @@ spec: maxLength: 63 pattern: "^[a-z0-9]([-\\.a-z0-9]*[a-z0-9])?$" {{- $featureGates := include "agones.featureGates" . | fromYaml }} - {{- include "fleetautoscaler.policy" (dict "includeChainPolicy" $featureGates.ScheduledAutoscaler) | indent 16 }} + {{- include "fleetautoscaler.policy" (dict "includeChainPolicy" $featureGates.ScheduledAutoscaler "includeSchedulePolicy" $featureGates.ScheduledAutoscaler "includePolicy" true) | indent 16 }} sync: type: object required: diff --git a/pkg/apis/autoscaling/v1/fleetautoscaler.go b/pkg/apis/autoscaling/v1/fleetautoscaler.go index f170380700..a8e1fe2de3 100644 --- a/pkg/apis/autoscaling/v1/fleetautoscaler.go +++ b/pkg/apis/autoscaling/v1/fleetautoscaler.go @@ -16,10 +16,15 @@ package v1 import ( "crypto/x509" + "errors" + "fmt" "net/url" + "strings" + "time" agonesv1 "agones.dev/agones/pkg/apis/agones/v1" "agones.dev/agones/pkg/util/runtime" + "github.com/robfig/cron/v3" admregv1 "k8s.io/api/admissionregistration/v1" apimachineryvalidation "k8s.io/apimachinery/pkg/api/validation" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -82,6 +87,16 @@ type FleetAutoscalerPolicy struct { // List policy config params. Present only if FleetAutoscalerPolicyType = List. // +optional List *ListPolicy `json:"list,omitempty"` + // [Stage:Dev] + // [FeatureFlag:ScheduledAutoscaler] + // Schedule policy config params. Present only if FleetAutoscalerPolicyType = Schedule. + // +optional + Schedule *SchedulePolicy `json:"schedule,omitempty"` + // [Stage:Dev] + // [FeatureFlag:ScheduledAutoscaler] + // Chain policy config params. Present only if FleetAutoscalerPolicyType = Chain. + // +optional + Chain ChainPolicy `json:"chain,omitempty"` } // FleetAutoscalerPolicyType is the policy for autoscaling @@ -118,6 +133,16 @@ const ( // ListPolicyType is for List based fleet autoscaling // nolint:revive // Linter contains comment doesn't start with ListPolicyType ListPolicyType FleetAutoscalerPolicyType = "List" + // [Stage:Dev] + // [FeatureFlag:ScheduledAutoscaler] + // SchedulePolicyType is for Schedule based fleet autoscaling + // nolint:revive // Linter contains comment doesn't start with SchedulePolicyType + SchedulePolicyType FleetAutoscalerPolicyType = "Schedule" + // [Stage:Dev] + // [FeatureFlag:ScheduledAutoscaler] + // ChainPolicyType is for Chain based fleet autoscaling + // nolint:revive // Linter contains comment doesn't start with ChainPolicyType + ChainPolicyType FleetAutoscalerPolicyType = "Chain" // FixedIntervalSyncType is a simple fixed interval based strategy for trigger autoscaling FixedIntervalSyncType FleetAutoscalerSyncType = "FixedInterval" @@ -195,6 +220,61 @@ type ListPolicy struct { BufferSize intstr.IntOrString `json:"bufferSize"` } +// Between defines the time period that the policy is eligible to be applied. +type Between struct { + // Start is the datetime that the policy is eligible to be applied. + // This field must conform to RFC3339 format. If this field not set or is in the past, the policy is eligible to be applied + // as soon as the fleet autoscaler is running. + Start metav1.Time `json:"start"` + + // End is the datetime that the policy is no longer eligible to be applied. + // This field must conform to RFC3339 format. If not set, the policy is always eligible to be applied, after the start time above. + End metav1.Time `json:"end"` +} + +// ActivePeriod defines the time period that the policy is applied. +type ActivePeriod struct { + // Timezone to be used for the startCron field. If not set, startCron is defaulted to the UTC timezone. + Timezone string `json:"timezone"` + + // StartCron defines when the policy should be applied. + // If not set, the policy is always to be applied within the start and end time. + // This field must conform to UNIX cron syntax. + StartCron string `json:"startCron"` + + // Duration is the length of time that the policy is applied. + // If not set, the duration is indefinite. + // A duration string is a possibly signed sequence of decimal numbers, + // (e.g. "300ms", "-1.5h" or "2h45m"). + // The representation limits the largest representable duration to approximately 290 years. + // Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". + Duration string `json:"duration"` +} + +// SchedulePolicy controls the desired behavior of the Schedule autoscaler policy. +type SchedulePolicy struct { + // Between defines the time period that the policy is eligible to be applied. + Between Between `json:"between"` + + // ActivePeriod defines the time period that the policy is applied. + ActivePeriod ActivePeriod `json:"activePeriod"` + + // Policy is the name of the policy to be applied. Required field. + Policy FleetAutoscalerPolicy `json:"policy"` +} + +// ChainEntry defines a single entry in the ChainPolicy. +type ChainEntry struct { + // ID is the unique identifier for a ChainEntry. If not set the identifier will be set to the index of chain entry. + ID string `json:"id"` + + // Policy is the name of the policy to be applied. Required field. + FleetAutoscalerPolicy `json:",inline"` +} + +// ChainPolicy controls the desired behavior of the Chain autoscaler policy. +type ChainPolicy []ChainEntry + // FixedIntervalSync controls the desired behavior of the fixed interval based sync. type FixedIntervalSync struct { // Seconds defines how often we run fleet autoscaling in seconds @@ -258,23 +338,35 @@ type FleetAutoscaleReview struct { // Validate validates the FleetAutoscaler scaling settings func (fas *FleetAutoscaler) Validate() field.ErrorList { + allErrs := fas.Spec.Policy.ValidatePolicy(field.NewPath("spec", "policy")) + + if fas.Spec.Sync != nil { + allErrs = append(allErrs, fas.Spec.Sync.FixedInterval.ValidateFixedIntervalSync(field.NewPath("spec", "sync", "fixedInterval"))...) + } + return allErrs +} + +// ValidatePolicy validates a FleetAutoscalerPolicy's settings. +func (f *FleetAutoscalerPolicy) ValidatePolicy(fldPath *field.Path) field.ErrorList { var allErrs field.ErrorList - switch fas.Spec.Policy.Type { + switch f.Type { case BufferPolicyType: - allErrs = fas.Spec.Policy.Buffer.ValidateBufferPolicy(field.NewPath("spec", "policy", "buffer")) + allErrs = f.Buffer.ValidateBufferPolicy(fldPath.Child("buffer")) case WebhookPolicyType: - allErrs = fas.Spec.Policy.Webhook.ValidateWebhookPolicy(field.NewPath("spec", "policy", "webhook")) + allErrs = f.Webhook.ValidateWebhookPolicy(fldPath.Child("webhook")) case CounterPolicyType: - allErrs = fas.Spec.Policy.Counter.ValidateCounterPolicy(field.NewPath("spec", "policy", "counter")) + allErrs = f.Counter.ValidateCounterPolicy(fldPath.Child("counter")) case ListPolicyType: - allErrs = fas.Spec.Policy.List.ValidateListPolicy(field.NewPath("spec", "policy", "list")) - } + allErrs = f.List.ValidateListPolicy(fldPath.Child("list")) - if fas.Spec.Sync != nil { - allErrs = append(allErrs, fas.Spec.Sync.FixedInterval.ValidateFixedIntervalSync(field.NewPath("spec", "sync", "fixedInterval"))...) + case SchedulePolicyType: + allErrs = f.Schedule.ValidateSchedulePolicy(fldPath.Child("schedule")) + + case ChainPolicyType: + allErrs = f.Chain.ValidateChainPolicy(fldPath.Child("chain")) } return allErrs } @@ -423,6 +515,86 @@ func (l *ListPolicy) ValidateListPolicy(fldPath *field.Path) field.ErrorList { return allErrs } +// ValidateSchedulePolicy validates the FleetAutoscaler Schedule policy settings. +func (s *SchedulePolicy) ValidateSchedulePolicy(fldPath *field.Path) field.ErrorList { + var allErrs field.ErrorList + if s == nil { + return append(allErrs, field.Required(fldPath, "schedule policy config params are missing")) + } + if !runtime.FeatureEnabled(runtime.FeatureScheduledAutoscaler) { + return append(allErrs, field.Forbidden(fldPath, "feature ScheduledAutoscaler must be enabled")) + } + if s.ActivePeriod.Timezone != "" { + if _, err := time.LoadLocation(s.ActivePeriod.Timezone); err != nil { + allErrs = append(allErrs, field.Invalid(fldPath.Child("activePeriod").Child("timezone"), s.ActivePeriod.Timezone, fmt.Sprintf("Error parsing timezone: %s\n", err))) + } + } + if !s.Between.End.IsZero() { + startTime := s.Between.Start.Time + endTime := s.Between.End.Time + var endErr error + if endTime.Before(time.Now()) { + allErrs = append(allErrs, field.Invalid(fldPath.Child("between").Child("end"), s.Between.End, "end time must be after the current time")) + endErr = errors.New("end time before current time") + } + + if !startTime.IsZero() && endErr == nil { + if endTime.Before(startTime) { + allErrs = append(allErrs, field.Invalid(fldPath.Child("between"), s.Between, "start time must be before end time")) + } + } + } + if s.ActivePeriod.StartCron != "" { + // If startCron is not a valid cron expression, append an error + if _, err := cron.ParseStandard(s.ActivePeriod.StartCron); err != nil { + allErrs = append(allErrs, field.Invalid(fldPath.Child("activePeriod").Child("startCron"), s.ActivePeriod.StartCron, fmt.Sprintf("invalid startCron: %s", err))) + } + // If the cron expression contains a CRON_TZ or TZ specification, append an error + if strings.Contains(s.ActivePeriod.StartCron, "TZ") { + allErrs = append(allErrs, field.Invalid(fldPath.Child("activePeriod").Child("startCron"), s.ActivePeriod.StartCron, "CRON_TZ or TZ used in activePeriod is not supported, please use the .schedule.timezone field to specify a timezone")) + } + } + if s.ActivePeriod.Duration != "" { + if _, err := time.ParseDuration(s.ActivePeriod.Duration); err != nil { + allErrs = append(allErrs, field.Invalid(fldPath.Child("activePeriod").Child("duration"), s.ActivePeriod.StartCron, fmt.Sprintf("invalid duration: %s", err))) + } + } + return allErrs +} + +// ValidateChainPolicy validates the FleetAutoscaler Chain policy settings. +func (c *ChainPolicy) ValidateChainPolicy(fldPath *field.Path) field.ErrorList { + var allErrs field.ErrorList + if c == nil { + return append(allErrs, field.Required(fldPath, "chain policy config params are missing")) + } + if !runtime.FeatureEnabled(runtime.FeatureScheduledAutoscaler) { + return append(allErrs, field.Forbidden(fldPath, "feature ScheduledAutoscaler must be enabled")) + } + seenIDs := make(map[string]bool) + for i, entry := range *c { + + // Ensure that all IDs are unique + if seenIDs[entry.ID] { + allErrs = append(allErrs, field.Invalid(fldPath, entry.ID, "id of chain entry must be unique")) + } else { + seenIDs[entry.ID] = true + } + // Ensure that chain entry has a policy + hasValidPolicy := entry.Buffer == nil && entry.Webhook == nil && entry.Counter == nil && entry.List == nil && entry.Schedule == nil + if entry.Type == "" || hasValidPolicy { + allErrs = append(allErrs, field.Required(fldPath.Index(i), "policy is missing")) + } + // Ensure the chain entry's policy is not a chain policy (to avoid nested chain policies) + if entry.Chain != nil { + allErrs = append(allErrs, field.Invalid(fldPath.Index(i), entry.FleetAutoscalerPolicy.Type, "chain policy cannot be used in chain policy")) + } + // Validate the chain entry's policy + allErrs = append(allErrs, entry.FleetAutoscalerPolicy.ValidatePolicy(fldPath.Index(i).Child("policy"))...) + } + return allErrs +} + // ValidateFixedIntervalSync validates the FixedIntervalSync settings func (i *FixedIntervalSync) ValidateFixedIntervalSync(fldPath *field.Path) field.ErrorList { var allErrs field.ErrorList diff --git a/pkg/apis/autoscaling/v1/fleetautoscaler_test.go b/pkg/apis/autoscaling/v1/fleetautoscaler_test.go index 0ddc2c0357..957cd07153 100644 --- a/pkg/apis/autoscaling/v1/fleetautoscaler_test.go +++ b/pkg/apis/autoscaling/v1/fleetautoscaler_test.go @@ -16,6 +16,7 @@ package v1 import ( "testing" + "time" "agones.dev/agones/pkg/util/runtime" "github.com/stretchr/testify/assert" @@ -456,6 +457,168 @@ func TestFleetAutoscalerListValidateUpdate(t *testing.T) { } } +func TestFleetAutoscalerScheduleValidateUpdate(t *testing.T) { + t.Parallel() + + modifiedFAS := func(f func(*FleetAutoscalerPolicy)) *FleetAutoscaler { + fas := scheduleFixture() + f(&fas.Spec.Policy) + return fas + } + + testCases := map[string]struct { + fas *FleetAutoscaler + featureFlags string + wantLength int + wantField string + }{ + "feature gate not turned on": { + fas: scheduleFixture(), + featureFlags: string(runtime.FeatureScheduledAutoscaler) + "=false", + wantLength: 1, + wantField: "spec.policy.schedule", + }, + "end time before current time": { + fas: modifiedFAS(func(fap *FleetAutoscalerPolicy) { + fap.Schedule.Between.End = mustParseDate("2024-07-03T15:59:59Z") + }), + featureFlags: string(runtime.FeatureScheduledAutoscaler) + "=true", + wantLength: 1, + wantField: "spec.policy.schedule.between.end", + }, + "end time before start time": { + fas: modifiedFAS(func(fap *FleetAutoscalerPolicy) { + mustParseDate("3999-06-15T15:59:59Z") + mustParseDate("3999-05-15T15:59:59Z") + fap.Schedule.Between.Start = mustParseDate("3999-06-15T15:59:59Z") + fap.Schedule.Between.End = mustParseDate("3999-05-15T15:59:59Z") + }), + featureFlags: string(runtime.FeatureScheduledAutoscaler) + "=true", + wantLength: 1, + wantField: "spec.policy.schedule.between", + }, + "invalid cron format": { + fas: modifiedFAS(func(fap *FleetAutoscalerPolicy) { + fap.Schedule.ActivePeriod.StartCron = "* * * * * * * *" + }), + featureFlags: string(runtime.FeatureScheduledAutoscaler) + "=true", + wantLength: 1, + wantField: "spec.policy.schedule.activePeriod.startCron", + }, + "invalid cron format with tz specification": { + fas: modifiedFAS(func(fap *FleetAutoscalerPolicy) { + fap.Schedule.ActivePeriod.StartCron = "CRON_TZ=America/New_York * * * * *" + }), + featureFlags: string(runtime.FeatureScheduledAutoscaler) + "=true", + wantLength: 1, + wantField: "spec.policy.schedule.activePeriod.startCron", + }, + } + + runtime.FeatureTestMutex.Lock() + defer runtime.FeatureTestMutex.Unlock() + + for name, tc := range testCases { + t.Run(name, func(t *testing.T) { + err := runtime.ParseFeatures(tc.featureFlags) + assert.NoError(t, err) + + causes := tc.fas.Validate() + + assert.Len(t, causes, tc.wantLength) + if tc.wantLength > 0 { + assert.Equal(t, tc.wantField, causes[0].Field) + } + }) + } +} + +func TestFleetAutoscalerChainValidateUpdate(t *testing.T) { + t.Parallel() + + modifiedFAS := func(f func(*FleetAutoscalerPolicy)) *FleetAutoscaler { + fas := chainFixture() + f(&fas.Spec.Policy) + return fas + } + + testCases := map[string]struct { + fas *FleetAutoscaler + featureFlags string + wantLength int + wantField string + }{ + "feature gate not turned on": { + fas: chainFixture(), + featureFlags: string(runtime.FeatureScheduledAutoscaler) + "=false", + wantLength: 1, + wantField: "spec.policy.chain", + }, + "duplicate id": { + fas: modifiedFAS(func(fap *FleetAutoscalerPolicy) { + fap.Chain[1].ID = "weekends" + }), + featureFlags: string(runtime.FeatureScheduledAutoscaler) + "=true", + wantLength: 1, + wantField: "spec.policy.chain", + }, + "missing policy": { + fas: modifiedFAS(func(fap *FleetAutoscalerPolicy) { + fap.Chain[0].FleetAutoscalerPolicy = FleetAutoscalerPolicy{} + }), + featureFlags: string(runtime.FeatureScheduledAutoscaler) + "=true", + wantLength: 1, + wantField: "spec.policy.chain[0]", + }, + "nested chain policy not allowed": { + fas: modifiedFAS(func(fap *FleetAutoscalerPolicy) { + fap.Chain[1].FleetAutoscalerPolicy = FleetAutoscalerPolicy{ + Type: ChainPolicyType, + Chain: ChainPolicy{ + { + FleetAutoscalerPolicy: FleetAutoscalerPolicy{ + Type: BufferPolicyType, + Buffer: &BufferPolicy{ + BufferSize: intstr.FromInt(5), + MaxReplicas: 10, + }, + }, + }, + }, + } + }), + featureFlags: string(runtime.FeatureScheduledAutoscaler) + "=true", + wantLength: 2, + wantField: "spec.policy.chain[1]", + }, + "invalid nested policy format": { + fas: modifiedFAS(func(fap *FleetAutoscalerPolicy) { + fap.Chain[1].FleetAutoscalerPolicy.Buffer.MinReplicas = 20 + }), + featureFlags: string(runtime.FeatureScheduledAutoscaler) + "=true", + wantLength: 1, + wantField: "spec.policy.chain[1].policy.buffer.minReplicas", + }, + } + + runtime.FeatureTestMutex.Lock() + defer runtime.FeatureTestMutex.Unlock() + + for name, tc := range testCases { + t.Run(name, func(t *testing.T) { + err := runtime.ParseFeatures(tc.featureFlags) + assert.NoError(t, err) + + causes := tc.fas.Validate() + + assert.Len(t, causes, tc.wantLength) + if tc.wantLength > 0 { + assert.Equal(t, tc.wantField, causes[0].Field) + } + }) + } +} + func TestFleetAutoscalerApplyDefaults(t *testing.T) { fas := &FleetAutoscaler{} @@ -474,6 +637,11 @@ func TestFleetAutoscalerApplyDefaults(t *testing.T) { assert.Equal(t, defaultIntervalSyncSeconds, fas.Spec.Sync.FixedInterval.Seconds) } +func mustParseDate(timeStr string) metav1.Time { + t, _ := time.Parse(time.RFC3339, timeStr) + return metav1.Date(t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute(), t.Second(), t.Nanosecond(), t.Location()) +} + func defaultFixture() *FleetAutoscaler { return customFixture(BufferPolicyType) } @@ -490,6 +658,14 @@ func listFixture() *FleetAutoscaler { return customFixture(ListPolicyType) } +func scheduleFixture() *FleetAutoscaler { + return customFixture(SchedulePolicyType) +} + +func chainFixture() *FleetAutoscaler { + return customFixture(ChainPolicyType) +} + func customFixture(t FleetAutoscalerPolicyType) *FleetAutoscaler { res := &FleetAutoscaler{ ObjectMeta: metav1.ObjectMeta{Name: "test"}, @@ -537,6 +713,67 @@ func customFixture(t FleetAutoscalerPolicyType) *FleetAutoscaler { BufferSize: intstr.FromInt(5), MaxCapacity: 10, } + case SchedulePolicyType: + res.Spec.Policy.Type = SchedulePolicyType + res.Spec.Policy.Buffer = nil + res.Spec.Policy.Schedule = &SchedulePolicy{ + Between: Between{ + Start: mustParseDate("2024-07-01T15:59:59Z"), + End: mustParseDate("9999-07-03T15:59:59Z"), + }, + ActivePeriod: ActivePeriod{ + Timezone: "", + StartCron: "* * * * 1-5", + Duration: "", + }, + Policy: FleetAutoscalerPolicy{ + Type: BufferPolicyType, + Buffer: &BufferPolicy{ + BufferSize: intstr.FromInt(5), + MaxReplicas: 10, + }, + }, + } + case ChainPolicyType: + res.Spec.Policy.Type = ChainPolicyType + res.Spec.Policy.Buffer = nil + res.Spec.Policy.Chain = ChainPolicy{ + { + ID: "weekends", + FleetAutoscalerPolicy: FleetAutoscalerPolicy{ + Type: SchedulePolicyType, + Schedule: &SchedulePolicy{ + Between: Between{ + Start: mustParseDate("2024-07-04T15:59:59Z"), + End: mustParseDate("9999-07-05T15:59:59Z"), + }, + ActivePeriod: ActivePeriod{ + Timezone: "", + StartCron: "* * * * 5-6", + Duration: "", + }, + Policy: FleetAutoscalerPolicy{ + Type: CounterPolicyType, + Counter: &CounterPolicy{ + Key: "playerCount", + BufferSize: intstr.FromInt(5), + MaxCapacity: 10, + }, + }, + }, + }, + }, + { + ID: "", + FleetAutoscalerPolicy: FleetAutoscalerPolicy{ + Type: BufferPolicyType, + Buffer: &BufferPolicy{ + BufferSize: intstr.FromInt(5), + MaxReplicas: 10, + }, + }, + }, + } } return res } diff --git a/pkg/apis/autoscaling/v1/zz_generated.deepcopy.go b/pkg/apis/autoscaling/v1/zz_generated.deepcopy.go index 499b0a096e..903ca92680 100644 --- a/pkg/apis/autoscaling/v1/zz_generated.deepcopy.go +++ b/pkg/apis/autoscaling/v1/zz_generated.deepcopy.go @@ -26,6 +26,40 @@ import ( runtime "k8s.io/apimachinery/pkg/runtime" ) +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ActivePeriod) DeepCopyInto(out *ActivePeriod) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ActivePeriod. +func (in *ActivePeriod) DeepCopy() *ActivePeriod { + if in == nil { + return nil + } + out := new(ActivePeriod) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Between) DeepCopyInto(out *Between) { + *out = *in + in.Start.DeepCopyInto(&out.Start) + in.End.DeepCopyInto(&out.End) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Between. +func (in *Between) DeepCopy() *Between { + if in == nil { + return nil + } + out := new(Between) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *BufferPolicy) DeepCopyInto(out *BufferPolicy) { *out = *in @@ -43,6 +77,45 @@ func (in *BufferPolicy) DeepCopy() *BufferPolicy { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ChainEntry) DeepCopyInto(out *ChainEntry) { + *out = *in + in.FleetAutoscalerPolicy.DeepCopyInto(&out.FleetAutoscalerPolicy) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ChainEntry. +func (in *ChainEntry) DeepCopy() *ChainEntry { + if in == nil { + return nil + } + out := new(ChainEntry) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in ChainPolicy) DeepCopyInto(out *ChainPolicy) { + { + in := &in + *out = make(ChainPolicy, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + return + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ChainPolicy. +func (in ChainPolicy) DeepCopy() ChainPolicy { + if in == nil { + return nil + } + out := new(ChainPolicy) + in.DeepCopyInto(out) + return *out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *CounterPolicy) DeepCopyInto(out *CounterPolicy) { *out = *in @@ -219,6 +292,18 @@ func (in *FleetAutoscalerPolicy) DeepCopyInto(out *FleetAutoscalerPolicy) { *out = new(ListPolicy) **out = **in } + if in.Schedule != nil { + in, out := &in.Schedule, &out.Schedule + *out = new(SchedulePolicy) + (*in).DeepCopyInto(*out) + } + if in.Chain != nil { + in, out := &in.Chain, &out.Chain + *out = make(ChainPolicy, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } return } @@ -308,6 +393,25 @@ func (in *ListPolicy) DeepCopy() *ListPolicy { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SchedulePolicy) DeepCopyInto(out *SchedulePolicy) { + *out = *in + in.Between.DeepCopyInto(&out.Between) + out.ActivePeriod = in.ActivePeriod + in.Policy.DeepCopyInto(&out.Policy) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SchedulePolicy. +func (in *SchedulePolicy) DeepCopy() *SchedulePolicy { + if in == nil { + return nil + } + out := new(SchedulePolicy) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *WebhookPolicy) DeepCopyInto(out *WebhookPolicy) { *out = *in diff --git a/pkg/client/applyconfiguration/autoscaling/v1/activeperiod.go b/pkg/client/applyconfiguration/autoscaling/v1/activeperiod.go new file mode 100644 index 0000000000..e97c7f656f --- /dev/null +++ b/pkg/client/applyconfiguration/autoscaling/v1/activeperiod.go @@ -0,0 +1,57 @@ +// Copyright 2024 Google LLC All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// This code was autogenerated. Do not edit directly. + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1 + +// ActivePeriodApplyConfiguration represents an declarative configuration of the ActivePeriod type for use +// with apply. +type ActivePeriodApplyConfiguration struct { + Timezone *string `json:"timezone,omitempty"` + StartCron *string `json:"startCron,omitempty"` + Duration *string `json:"duration,omitempty"` +} + +// ActivePeriodApplyConfiguration constructs an declarative configuration of the ActivePeriod type for use with +// apply. +func ActivePeriod() *ActivePeriodApplyConfiguration { + return &ActivePeriodApplyConfiguration{} +} + +// WithTimezone sets the Timezone field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Timezone field is set to the value of the last call. +func (b *ActivePeriodApplyConfiguration) WithTimezone(value string) *ActivePeriodApplyConfiguration { + b.Timezone = &value + return b +} + +// WithStartCron sets the StartCron field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the StartCron field is set to the value of the last call. +func (b *ActivePeriodApplyConfiguration) WithStartCron(value string) *ActivePeriodApplyConfiguration { + b.StartCron = &value + return b +} + +// WithDuration sets the Duration field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Duration field is set to the value of the last call. +func (b *ActivePeriodApplyConfiguration) WithDuration(value string) *ActivePeriodApplyConfiguration { + b.Duration = &value + return b +} diff --git a/pkg/client/applyconfiguration/autoscaling/v1/between.go b/pkg/client/applyconfiguration/autoscaling/v1/between.go new file mode 100644 index 0000000000..696906a9e7 --- /dev/null +++ b/pkg/client/applyconfiguration/autoscaling/v1/between.go @@ -0,0 +1,52 @@ +// Copyright 2024 Google LLC All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// This code was autogenerated. Do not edit directly. + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1 + +import ( + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// BetweenApplyConfiguration represents an declarative configuration of the Between type for use +// with apply. +type BetweenApplyConfiguration struct { + Start *v1.Time `json:"start,omitempty"` + End *v1.Time `json:"end,omitempty"` +} + +// BetweenApplyConfiguration constructs an declarative configuration of the Between type for use with +// apply. +func Between() *BetweenApplyConfiguration { + return &BetweenApplyConfiguration{} +} + +// WithStart sets the Start field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Start field is set to the value of the last call. +func (b *BetweenApplyConfiguration) WithStart(value v1.Time) *BetweenApplyConfiguration { + b.Start = &value + return b +} + +// WithEnd sets the End field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the End field is set to the value of the last call. +func (b *BetweenApplyConfiguration) WithEnd(value v1.Time) *BetweenApplyConfiguration { + b.End = &value + return b +} diff --git a/pkg/client/applyconfiguration/autoscaling/v1/chainentry.go b/pkg/client/applyconfiguration/autoscaling/v1/chainentry.go new file mode 100644 index 0000000000..39dba55d10 --- /dev/null +++ b/pkg/client/applyconfiguration/autoscaling/v1/chainentry.go @@ -0,0 +1,100 @@ +// Copyright 2024 Google LLC All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// This code was autogenerated. Do not edit directly. + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1 + +import ( + autoscalingv1 "agones.dev/agones/pkg/apis/autoscaling/v1" +) + +// ChainEntryApplyConfiguration represents an declarative configuration of the ChainEntry type for use +// with apply. +type ChainEntryApplyConfiguration struct { + ID *string `json:"id,omitempty"` + FleetAutoscalerPolicyApplyConfiguration `json:",inline"` +} + +// ChainEntryApplyConfiguration constructs an declarative configuration of the ChainEntry type for use with +// apply. +func ChainEntry() *ChainEntryApplyConfiguration { + return &ChainEntryApplyConfiguration{} +} + +// WithID sets the ID field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ID field is set to the value of the last call. +func (b *ChainEntryApplyConfiguration) WithID(value string) *ChainEntryApplyConfiguration { + b.ID = &value + return b +} + +// WithType sets the Type field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Type field is set to the value of the last call. +func (b *ChainEntryApplyConfiguration) WithType(value autoscalingv1.FleetAutoscalerPolicyType) *ChainEntryApplyConfiguration { + b.Type = &value + return b +} + +// WithBuffer sets the Buffer field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Buffer field is set to the value of the last call. +func (b *ChainEntryApplyConfiguration) WithBuffer(value *BufferPolicyApplyConfiguration) *ChainEntryApplyConfiguration { + b.Buffer = value + return b +} + +// WithWebhook sets the Webhook field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Webhook field is set to the value of the last call. +func (b *ChainEntryApplyConfiguration) WithWebhook(value *WebhookPolicyApplyConfiguration) *ChainEntryApplyConfiguration { + b.Webhook = value + return b +} + +// WithCounter sets the Counter field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Counter field is set to the value of the last call. +func (b *ChainEntryApplyConfiguration) WithCounter(value *CounterPolicyApplyConfiguration) *ChainEntryApplyConfiguration { + b.Counter = value + return b +} + +// WithList sets the List field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the List field is set to the value of the last call. +func (b *ChainEntryApplyConfiguration) WithList(value *ListPolicyApplyConfiguration) *ChainEntryApplyConfiguration { + b.List = value + return b +} + +// WithSchedule sets the Schedule field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Schedule field is set to the value of the last call. +func (b *ChainEntryApplyConfiguration) WithSchedule(value *SchedulePolicyApplyConfiguration) *ChainEntryApplyConfiguration { + b.Schedule = value + return b +} + +// WithChain sets the Chain field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Chain field is set to the value of the last call. +func (b *ChainEntryApplyConfiguration) WithChain(value autoscalingv1.ChainPolicy) *ChainEntryApplyConfiguration { + b.Chain = &value + return b +} diff --git a/pkg/client/applyconfiguration/autoscaling/v1/fleetautoscalerpolicy.go b/pkg/client/applyconfiguration/autoscaling/v1/fleetautoscalerpolicy.go index 1441bd4eee..bf3b31fd94 100644 --- a/pkg/client/applyconfiguration/autoscaling/v1/fleetautoscalerpolicy.go +++ b/pkg/client/applyconfiguration/autoscaling/v1/fleetautoscalerpolicy.go @@ -25,11 +25,13 @@ import ( // FleetAutoscalerPolicyApplyConfiguration represents an declarative configuration of the FleetAutoscalerPolicy type for use // with apply. type FleetAutoscalerPolicyApplyConfiguration struct { - Type *v1.FleetAutoscalerPolicyType `json:"type,omitempty"` - Buffer *BufferPolicyApplyConfiguration `json:"buffer,omitempty"` - Webhook *WebhookPolicyApplyConfiguration `json:"webhook,omitempty"` - Counter *CounterPolicyApplyConfiguration `json:"counter,omitempty"` - List *ListPolicyApplyConfiguration `json:"list,omitempty"` + Type *v1.FleetAutoscalerPolicyType `json:"type,omitempty"` + Buffer *BufferPolicyApplyConfiguration `json:"buffer,omitempty"` + Webhook *WebhookPolicyApplyConfiguration `json:"webhook,omitempty"` + Counter *CounterPolicyApplyConfiguration `json:"counter,omitempty"` + List *ListPolicyApplyConfiguration `json:"list,omitempty"` + Schedule *SchedulePolicyApplyConfiguration `json:"schedule,omitempty"` + Chain *v1.ChainPolicy `json:"chain,omitempty"` } // FleetAutoscalerPolicyApplyConfiguration constructs an declarative configuration of the FleetAutoscalerPolicy type for use with @@ -77,3 +79,19 @@ func (b *FleetAutoscalerPolicyApplyConfiguration) WithList(value *ListPolicyAppl b.List = value return b } + +// WithSchedule sets the Schedule field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Schedule field is set to the value of the last call. +func (b *FleetAutoscalerPolicyApplyConfiguration) WithSchedule(value *SchedulePolicyApplyConfiguration) *FleetAutoscalerPolicyApplyConfiguration { + b.Schedule = value + return b +} + +// WithChain sets the Chain field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Chain field is set to the value of the last call. +func (b *FleetAutoscalerPolicyApplyConfiguration) WithChain(value v1.ChainPolicy) *FleetAutoscalerPolicyApplyConfiguration { + b.Chain = &value + return b +} diff --git a/pkg/client/applyconfiguration/autoscaling/v1/schedulepolicy.go b/pkg/client/applyconfiguration/autoscaling/v1/schedulepolicy.go new file mode 100644 index 0000000000..4dec072c99 --- /dev/null +++ b/pkg/client/applyconfiguration/autoscaling/v1/schedulepolicy.go @@ -0,0 +1,57 @@ +// Copyright 2024 Google LLC All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// This code was autogenerated. Do not edit directly. + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1 + +// SchedulePolicyApplyConfiguration represents an declarative configuration of the SchedulePolicy type for use +// with apply. +type SchedulePolicyApplyConfiguration struct { + Between *BetweenApplyConfiguration `json:"between,omitempty"` + ActivePeriod *ActivePeriodApplyConfiguration `json:"activePeriod,omitempty"` + Policy *FleetAutoscalerPolicyApplyConfiguration `json:"policy,omitempty"` +} + +// SchedulePolicyApplyConfiguration constructs an declarative configuration of the SchedulePolicy type for use with +// apply. +func SchedulePolicy() *SchedulePolicyApplyConfiguration { + return &SchedulePolicyApplyConfiguration{} +} + +// WithBetween sets the Between field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Between field is set to the value of the last call. +func (b *SchedulePolicyApplyConfiguration) WithBetween(value *BetweenApplyConfiguration) *SchedulePolicyApplyConfiguration { + b.Between = value + return b +} + +// WithActivePeriod sets the ActivePeriod field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ActivePeriod field is set to the value of the last call. +func (b *SchedulePolicyApplyConfiguration) WithActivePeriod(value *ActivePeriodApplyConfiguration) *SchedulePolicyApplyConfiguration { + b.ActivePeriod = value + return b +} + +// WithPolicy sets the Policy field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Policy field is set to the value of the last call. +func (b *SchedulePolicyApplyConfiguration) WithPolicy(value *FleetAutoscalerPolicyApplyConfiguration) *SchedulePolicyApplyConfiguration { + b.Policy = value + return b +} diff --git a/pkg/client/applyconfiguration/utils.go b/pkg/client/applyconfiguration/utils.go index 57e9be63bf..913c7b8e91 100644 --- a/pkg/client/applyconfiguration/utils.go +++ b/pkg/client/applyconfiguration/utils.go @@ -83,8 +83,14 @@ func ForKind(kind schema.GroupVersionKind) interface{} { return &agonesv1.SdkServerApplyConfiguration{} // Group=autoscaling.agones.dev, Version=v1 + case autoscalingv1.SchemeGroupVersion.WithKind("ActivePeriod"): + return &applyconfigurationautoscalingv1.ActivePeriodApplyConfiguration{} + case autoscalingv1.SchemeGroupVersion.WithKind("Between"): + return &applyconfigurationautoscalingv1.BetweenApplyConfiguration{} case autoscalingv1.SchemeGroupVersion.WithKind("BufferPolicy"): return &applyconfigurationautoscalingv1.BufferPolicyApplyConfiguration{} + case autoscalingv1.SchemeGroupVersion.WithKind("ChainEntry"): + return &applyconfigurationautoscalingv1.ChainEntryApplyConfiguration{} case autoscalingv1.SchemeGroupVersion.WithKind("CounterPolicy"): return &applyconfigurationautoscalingv1.CounterPolicyApplyConfiguration{} case autoscalingv1.SchemeGroupVersion.WithKind("FixedIntervalSync"): @@ -101,6 +107,8 @@ func ForKind(kind schema.GroupVersionKind) interface{} { return &applyconfigurationautoscalingv1.FleetAutoscalerSyncApplyConfiguration{} case autoscalingv1.SchemeGroupVersion.WithKind("ListPolicy"): return &applyconfigurationautoscalingv1.ListPolicyApplyConfiguration{} + case autoscalingv1.SchemeGroupVersion.WithKind("SchedulePolicy"): + return &applyconfigurationautoscalingv1.SchedulePolicyApplyConfiguration{} case autoscalingv1.SchemeGroupVersion.WithKind("WebhookPolicy"): return &applyconfigurationautoscalingv1.WebhookPolicyApplyConfiguration{} diff --git a/site/content/en/docs/Reference/agones_crd_api_reference.html b/site/content/en/docs/Reference/agones_crd_api_reference.html index e73a9ab606..a46782edf1 100644 --- a/site/content/en/docs/Reference/agones_crd_api_reference.html +++ b/site/content/en/docs/Reference/agones_crd_api_reference.html @@ -3,10 +3,13 @@ description="Detailed list of Agones Custom Resource Definitions available" +++ -{{% feature expiryVersion="1.41.0" %}} +{{% feature expiryVersion="1.43.0" %}}
Packages:
Package v1 is the v1 version of the API.
Resource Types: --
GameServerAllocation is the data structure for allocating against a set of
-GameServers, defined selectors
selectors
Fleet is the data structure for a Fleet resource
-allocation.agones.dev/v1
+agones.dev/v1
|
@@ -56,7 +59,7 @@ GameServerAllocation |
+Fleet |
||||||||||||||||
@@ -76,8 +79,8 @@ GameServerAllocation
spec
-
-GameServerAllocationSpec
+
+FleetSpec
GameServerAllocation
status
-
-GameServerAllocationStatus
+
+FleetStatus
|
-(Appears on: -GameServerAllocationSpec) -
--
CounterAction is an optional action that can be performed on a Counter at allocation.
+GameServer is the data structure for a GameServer resource.
+It is worth noting that while there is a GameServerStatus
Status entry for the GameServer
, it is not
+defined as a subresource - unlike Fleet
and other Agones resources.
+This is so that we can retain the ability to change multiple aspects of a GameServer
in a single atomic operation,
+which is particularly useful for operations such as allocation.
-action
-
-string
-
+apiVersion
+string |
+
+
+agones.dev/v1
+
|
+
-(Optional)
- Action must to either “Increment” or “Decrement” the Counter’s Count. Must also define the Amount. +kind
+string
|
+GameServer |
-amount
+metadata
-int64
+
+Kubernetes meta/v1.ObjectMeta
+
|
-(Optional)
- Amount is the amount to increment or decrement the Count. Must be a positive integer. +Refer to the Kubernetes API documentation for the fields of the +metadata field.
|
-capacity
+spec
-int64
+
+GameServerSpec
+
|
-(Optional)
- Capacity is the amount to update the maximum capacity of the Counter to this number. Min 0, Max int64. - |
-
-(Appears on: -GameServerSelector) -
--
CounterSelector is the filter options for a GameServer based on the count and/or available capacity.
- +Field | -Description | +
+container
+
+string
+
+ |
+
+ Container specifies which Pod container is the game server. Only required if there is more than one +container defined + |
---|---|---|---|
-minCount
+ports
-int64
+
+[]GameServerPort
+
|
-(Optional)
- MinCount is the minimum current value. Defaults to 0. +Ports are the array of ports that can be exposed via the game server |
||
-maxCount
+health
-int64
+
+Health
+
|
-(Optional)
- MaxCount is the maximum current value. Defaults to 0, which translates as max(in64). +Health configures health checking |
||
-minAvailable
+scheduling
-int64
+agones.dev/agones/pkg/apis.SchedulingStrategy
|
-(Optional)
- MinAvailable specifies the minimum capacity (current capacity - current count) available on a GameServer. Defaults to 0. +Scheduling strategy. Defaults to “Packed” |
||
-maxAvailable
+sdkServer
-int64
+
+SdkServer
+
|
-(Optional)
- MaxAvailable specifies the maximum capacity (current capacity - current count) available on a GameServer. Defaults to 0, which translates to max(int64). - |
-
-(Appears on: -GameServerAllocation) -
--
GameServerAllocationSpec is the spec for a GameServerAllocation
- -Field | -Description | -
---|---|
-multiClusterSetting
-
-
-MultiClusterSetting
-
-
- |
-
- MultiClusterPolicySelector if specified, multi-cluster policies are applied. -Otherwise, allocation will happen locally. +SdkServer specifies parameters for the Agones SDK Server sidecar container |
-required
+template
-
-GameServerSelector
+
+Kubernetes core/v1.PodTemplateSpec
|
- Deprecated: use field Selectors instead. If Selectors is set, this field is ignored. -Required is the GameServer selector from which to choose GameServers from. -Defaults to all GameServers. +Template describes the Pod that will be created for the GameServer |
-preferred
+players
-
-[]GameServerSelector
+
+PlayersSpec
|
- Deprecated: use field Selectors instead. If Selectors is set, this field is ignored.
-Preferred is an ordered list of preferred GameServer selectors
-that are optional to be fulfilled, but will be searched before the (Alpha, PlayerTracking feature flag) Players provides the configuration for player tracking features. |
-priorities
+counters
-
-[]Priority
+
+map[string]agones.dev/agones/pkg/apis/agones/v1.CounterStatus
|
(Optional)
- [Stage: Alpha]
-[FeatureFlag:CountsAndLists]
- Priority of sorting is in descending importance. I.e. The position 0 For For (Beta, CountsAndLists feature flag) Counters provides the configuration for tracking of int64 values against a GameServer. +Keys must be declared at GameServer creation time. |
-selectors
+lists
-
-[]GameServerSelector
+
+map[string]agones.dev/agones/pkg/apis/agones/v1.ListStatus
|
- Ordered list of GameServer label selectors. -If the first selector is not matched, the selection attempts the second selector, and so on. -This is useful for things like smoke testing of new game servers. -Note: This field can only be set if neither Required or Preferred is set. - |
-
-scheduling
-
-agones.dev/agones/pkg/apis.SchedulingStrategy
-
- |
-
- Scheduling strategy. Defaults to “Packed”. +(Optional) +(Beta, CountsAndLists feature flag) Lists provides the configuration for tracking of lists of up to 1000 values against a GameServer. +Keys must be declared at GameServer creation time. |
-metadata
+eviction
-
-MetaPatch
+
+Eviction
|
- MetaPatch is optional custom metadata that is added to the game server at allocation -You can use this to tell the server necessary session data +(Optional) +Eviction specifies the eviction tolerance of the GameServer. Defaults to “Never”. |
-counters
-
-
-map[string]agones.dev/agones/pkg/apis/allocation/v1.CounterAction
-
-
- |
-
-(Optional)
- [Stage: Alpha] -[FeatureFlag:CountsAndLists] -Counter actions to perform during allocation. + |
lists
+status
-
-map[string]agones.dev/agones/pkg/apis/allocation/v1.ListAction
+
+GameServerStatus
[Stage: Alpha] -[FeatureFlag:CountsAndLists] -List actions to perform during allocation.
string
alias)-(Appears on: -GameServerAllocationStatus) -
--
GameServerAllocationState is the Allocation state
- --(Appears on: -GameServerAllocation) -
--
GameServerAllocationStatus is the status for an GameServerAllocation resource
+GameServerSet is the data structure for a set of GameServers. +This matches philosophically with the relationship between +Deployments and ReplicaSets
-state
-
-
-GameServerAllocationState
-
-
- |
+
- GameServerState is the current state of an GameServerAllocation, e.g. Allocated, or UnAllocated +
+agones.dev/v1
+
|
|
-gameServerName
-
+kind
string
-
- |
-+ | GameServerSet |
-ports
+metadata
-
-[]GameServerStatusPort
+
+Kubernetes meta/v1.ObjectMeta
|
+Refer to the Kubernetes API documentation for the fields of the
+metadata field.
|
|
-address
+spec
-string
+
+GameServerSetSpec
+
|
- | -
-addresses
+replicas
-
-[]Kubernetes core/v1.NodeAddress
-
+int32
|
+ Replicas are the number of GameServers that should be in this set |
-nodeName
+allocationOverflow
-string
+
+AllocationOverflow
+
|
+(Optional)
+ Labels and Annotations to apply to GameServers when the number of Allocated GameServers drops below
+the desired replicas on the underlying |
-source
+scheduling
-string
+agones.dev/agones/pkg/apis.SchedulingStrategy
|
- If the allocation is from a remote cluster, Source is the endpoint of the remote agones-allocator. -Otherwise, Source is “local” +Scheduling strategy. Defaults to “Packed”. |
-metadata
+priorities
-
-GameServerMetadata
+
+[]Priority
|
+(Optional)
+ [Stage: Beta]
+[FeatureFlag:CountsAndLists]
+ Priority of sorting is in descending importance. I.e. The position 0 For For |
-counters
+template
-
-map[string]agones.dev/agones/pkg/apis/agones/v1.CounterStatus
+
+GameServerTemplateSpec
|
+ Template the GameServer template to apply for this GameServerSet + |
+
lists
+status
-
-map[string]agones.dev/agones/pkg/apis/agones/v1.ListStatus
+
+GameServerSetStatus
(Appears on: -GameServerAllocationStatus) +FleetStatus, +GameServerSetStatus)
-
GameServerMetadata is the metadata from the allocated game server at allocation time
+AggregatedCounterStatus stores total and allocated Counter tracking values
-labels
+allocatedCount
-map[string]string
+int64
|
@@ -697,147 +577,82 @@ GameServerMetadata |
-annotations
+allocatedCapacity
-map[string]string
+int64
|
-(Appears on: -GameServerAllocationSpec) -
--
GameServerSelector contains all the filter options for selecting -a GameServer for allocation.
- -Field | -Description | -
---|---|
-LabelSelector
+count
-
-Kubernetes meta/v1.LabelSelector
-
+int64
|
-
-(Members of See: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ |
-gameServerState
+capacity
-
-GameServerState
-
+int64
|
- GameServerState specifies which State is the filter to be used when attempting to retrieve a GameServer -via Allocation. Defaults to “Ready”. The only other option is “Allocated”, which can be used in conjunction with -label/annotation/player selectors to retrieve an already Allocated GameServer. |
+(Appears on: +FleetStatus, +GameServerSetStatus) +
++
AggregatedListStatus stores total and allocated List tracking values
+ +
-players
-
-
-PlayerSelector
-
-
- |
-
-(Optional)
- [Stage:Alpha] -[FeatureFlag:PlayerAllocationFilter] -Players provides a filter on minimum and maximum values for player capacity when retrieving a GameServer -through Allocation. Defaults to no limits. - |
+Field | +Description |
---|---|---|---|
-counters
+allocatedCount
-
-map[string]agones.dev/agones/pkg/apis/allocation/v1.CounterSelector
-
+int64
|
-(Optional)
- [Stage: Alpha] -[FeatureFlag:CountsAndLists] -Counters provides filters on minimum and maximum values -for a Counter’s count and available capacity when retrieving a GameServer through Allocation. -Defaults to no limits. |
||
-lists
+allocatedCapacity
-
-map[string]agones.dev/agones/pkg/apis/allocation/v1.ListSelector
-
+int64
|
-(Optional)
- [Stage: Alpha] -[FeatureFlag:CountsAndLists] -Lists provides filters on minimum and maximum values -for List capacity, and for the existence of a value in a List, when retrieving a GameServer -through Allocation. Defaults to no limits. |
-(Appears on: -GameServerAllocationSpec) -
--
ListAction is an optional action that can be performed on a List at allocation.
- -Field | -Description | -
---|---|
-addValues
+count
-[]string
+int64
|
-(Optional)
- AddValues appends values to a List’s Values array. Any duplicate values will be ignored. |
-(Optional)
- Capacity updates the maximum capacity of the Counter to this number. Min 0, Max 1000. |
(Appears on: -GameServerSelector) +FleetStatus, +GameServerSetStatus)
-
ListSelector is the filter options for a GameServer based on List available capacity and/or the -existence of a value in a List.
+AggregatedPlayerStatus stores total player tracking values
-containsValue
-
-string
-
- |
-
-(Optional)
- ContainsValue says to only match GameServers who has this value in the list. Defaults to “”, which is all. - |
-
-minAvailable
+count
int64
|
-(Optional)
- MinAvailable specifies the minimum capacity (current capacity - current count) available on a GameServer. Defaults to 0. |
-maxAvailable
+capacity
int64
|
-(Optional)
- MaxAvailable specifies the maximum capacity (current capacity - current count) available on a GameServer. Defaults to 0, which is translated as max(int64). |
(Appears on: -GameServerAllocationSpec) +FleetSpec, +GameServerSetSpec)
-
MetaPatch is the metadata used to patch the GameServer metadata on allocation
+AllocationOverflow specifies what labels and/or annotations to apply on Allocated GameServers
+if the desired number of the underlying GameServerSet
drops below the number of Allocated GameServers
+attached to it.
+(Optional)
+ Labels to be applied to the |
+(Optional)
+ Annotations to be applied to the |
(Appears on: -GameServerAllocationSpec) +GameServerAllocationStatus, +GameServerSpec, +GameServerStatus)
-
MultiClusterSetting specifies settings for multi-cluster allocation.
+CounterStatus stores the current counter values and maximum capacity
-enabled
+count
-bool
+int64
|
@@ -978,11 +784,9 @@ MultiClusterSetting |
-policySelector
+capacity
-
-Kubernetes meta/v1.LabelSelector
-
+int64
|
@@ -990,14 +794,15 @@ MultiClusterSetting |
(Appears on: -GameServerSelector) +GameServerSpec, +GameServerStatus)
-
PlayerSelector is the filter options for a GameServer based on player counts
+Eviction specifies the eviction tolerance of the GameServer
-minAvailable
-
-int64
-
- |
-- | -
-maxAvailable
+safe
-int64
+
+EvictionSafe
+
|
+ Game server supports termination via SIGTERM: +- Always: Allow eviction for both Cluster Autoscaler and node drain for upgrades +- OnUpgrade: Allow eviction for upgrades alone +- Never (default): Pod should run to completion |
string
alias)-
Package v1 is the v1 version of the API.
+(Appears on: +Eviction) -Resource Types: - -+
EvictionSafe specified whether the game server supports termination via SIGTERM
+ +-
FleetAutoscaler is the data structure for a FleetAutoscaler resource
+(Appears on: +Fleet) + ++
FleetSpec is the spec for a Fleet
-apiVersion
-string |
-
-
-autoscaling.agones.dev/v1
-
+replicas
+
+int32
+
|
-||||||
-kind
-string
+Replicas are the number of GameServers that should be in this set. Defaults to 0. |
-FleetAutoscaler |
||||||
-metadata
+allocationOverflow
-
-Kubernetes meta/v1.ObjectMeta
+
+AllocationOverflow
|
-Refer to the Kubernetes API documentation for the fields of the
-metadata field.
+(Optional)
+Labels and/or Annotations to apply to overflowing GameServers when the number of Allocated GameServers is more
+than the desired replicas on the underlying |
||||||
-spec
+strategy
-
-FleetAutoscalerSpec
+
+Kubernetes apps/v1.DeploymentStrategy
|
- - -
[Stage: Beta]
+[FeatureFlag:CountsAndLists]
+ Priority of sorting is in descending importance. I.e. The position 0 For For |
||||||
-status
+template
-
-FleetAutoscalerStatus
+
+GameServerTemplateSpec
|
+ Template the GameServer template to apply for this Fleet |
(Appears on: -FleetAutoscalerPolicy) +Fleet, +FleetAutoscaleRequest)
-
BufferPolicy controls the desired behavior of the buffer policy.
+FleetStatus is the status of a Fleet
-maxReplicas
+replicas
int32
|
- MaxReplicas is the maximum amount of replicas that the fleet may have. -It must be bigger than both MinReplicas and BufferSize +Replicas the total number of current GameServer replicas |
-minReplicas
+readyReplicas
int32
|
- MinReplicas is the minimum amount of replicas that the fleet must have -If zero, it is ignored. -If non zero, it must be smaller than MaxReplicas and bigger than BufferSize +ReadyReplicas are the number of Ready GameServer replicas |
-bufferSize
+reservedReplicas
-k8s.io/apimachinery/pkg/util/intstr.IntOrString
+int32
|
- BufferSize defines how many replicas the autoscaler tries to have ready all the time -Value can be an absolute number (ex: 5) or a percentage of desired gs instances (ex: 15%) -Absolute number is calculated from percentage by rounding up. -Example: when this is set to 20%, the autoscaler will make sure that 20% -of the fleet’s game server replicas are ready. When this is set to 20, -the autoscaler will make sure that there are 20 available game servers -Must be bigger than 0 -Note: by “ready” we understand in this case “non-allocated”; this is done to ensure robustness -and computation stability in different edge case (fleet just created, not enough -capacity in the cluster etc) +ReservedReplicas are the total number of Reserved GameServer replicas in this fleet. +Reserved instances won’t be deleted on scale down, but won’t cause an autoscaler to scale up. |
-(Appears on: -FleetAutoscalerPolicy) -
--
CounterPolicy controls the desired behavior of the Counter autoscaler policy.
- -Field | -Description | -
---|---|
-key
+allocatedReplicas
-string
+int32
|
- Key is the name of the Counter. Required field. +AllocatedReplicas are the number of Allocated GameServer replicas |
-maxCapacity
+players
-int64
+
+AggregatedPlayerStatus
+
|
- MaxCapacity is the maximum aggregate Counter total capacity across the fleet. -MaxCapacity must be bigger than both MinCapacity and BufferSize. Required field. +(Optional) +[Stage:Alpha] +[FeatureFlag:PlayerTracking] +Players are the current total player capacity and count for this Fleet |
-minCapacity
+counters
-int64
+
+map[string]agones.dev/agones/pkg/apis/agones/v1.AggregatedCounterStatus
+
|
- MinCapacity is the minimum aggregate Counter total capacity across the fleet. -If zero, MinCapacity is ignored. -If non zero, MinCapacity must be smaller than MaxCapacity and bigger than BufferSize. +(Optional) +(Beta, CountsAndLists feature flag) Counters provides aggregated Counter capacity and Counter +count for this Fleet. |
-bufferSize
+lists
-k8s.io/apimachinery/pkg/util/intstr.IntOrString
+
+map[string]agones.dev/agones/pkg/apis/agones/v1.AggregatedListStatus
+
|
- BufferSize is the size of a buffer of counted items that are available in the Fleet (available -capacity). Value can be an absolute number (ex: 5) or a percentage of desired gs instances -(ex: 5%). An absolute number is calculated from percentage by rounding up. -Must be bigger than 0. Required field. +(Optional) +(Beta, CountsAndLists feature flag) Lists provides aggregated List capacityv and List values +for this Fleet. |
(Appears on: -FleetAutoscalerSync) +GameServerSpec)
-
FixedIntervalSync controls the desired behavior of the fixed interval based sync.
+GameServerPort defines a set of Ports that +are to be exposed via the GameServer
-seconds
+name
-int32
+string
|
- Seconds defines how often we run fleet autoscaling in seconds +Name is the descriptive name of the port |
-(Appears on: -FleetAutoscaleReview) -
--
FleetAutoscaleRequest defines the request to webhook autoscaler endpoint
- -Field | -Description | +
+range
+
+string
+
+ |
+
+(Optional)
+ (Alpha, PortRanges feature flag) Range is the port range name from which to select a port when using a +‘Dynamic’ or ‘Passthrough’ port policy. + |
---|---|---|---|
-uid
+portPolicy
-k8s.io/apimachinery/pkg/types.UID
+
+PortPolicy
+
|
- UID is an identifier for the individual request/response. It allows us to distinguish instances of requests which are -otherwise identical (parallel requests, requests when earlier requests did not modify etc) -The UID is meant to track the round trip (request/response) between the Autoscaler and the WebHook, not the user request. -It is suitable for correlating log entries between the webhook and apiserver, for either auditing or debugging. +PortPolicy defines the policy for how the HostPort is populated.
+Dynamic port will allocate a HostPort within the selected MIN_PORT and MAX_PORT range passed to the controller
+at installation time.
+When |
||
-name
+container
string
|
- Name is the name of the Fleet being scaled +(Optional) +Container is the name of the container on which to open the port. Defaults to the game server container. |
||
-namespace
+containerPort
-string
+int32
|
- Namespace is the namespace associated with the request (if any). +ContainerPort is the port that is being opened on the specified container’s process |
||
-status
+hostPort
-
-FleetStatus
+int32
+
+ |
+
+ HostPort the port exposed on the host for clients to connect to + |
+||
+protocol
+
+
+Kubernetes core/v1.Protocol
|
- The Fleet’s status values +Protocol is the network protocol being used. Defaults to UDP. TCP and TCPUDP are other options. |
(Appears on: -FleetAutoscaleReview) +GameServerSet)
-
FleetAutoscaleResponse defines the response of webhook autoscaler endpoint
+GameServerSetSpec the specification for GameServerSet
-uid
+replicas
-k8s.io/apimachinery/pkg/types.UID
+int32
|
- UID is an identifier for the individual request/response. -This should be copied over from the corresponding FleetAutoscaleRequest. +Replicas are the number of GameServers that should be in this set |
-scale
+allocationOverflow
-bool
+
+AllocationOverflow
+
|
- Set to false if no scaling should occur to the Fleet +(Optional) +Labels and Annotations to apply to GameServers when the number of Allocated GameServers drops below
+the desired replicas on the underlying |
-replicas
+scheduling
-int32
+agones.dev/agones/pkg/apis.SchedulingStrategy
|
- The targeted replica count +Scheduling strategy. Defaults to “Packed”. |
-
FleetAutoscaleReview is passed to the webhook with a populated Request value, -and then returned with a populated Response.
- -Field | -Description | -
---|---|
-request
+priorities
-
-FleetAutoscaleRequest
+
+[]Priority
|
+(Optional)
+ [Stage: Beta]
+[FeatureFlag:CountsAndLists]
+ Priority of sorting is in descending importance. I.e. The position 0 For For |
-response
+template
-
-FleetAutoscaleResponse
+
+GameServerTemplateSpec
|
+ Template the GameServer template to apply for this GameServerSet |
(Appears on: -FleetAutoscalerSpec) +GameServerSet)
-
FleetAutoscalerPolicy describes how to scale a fleet
+GameServerSetStatus is the status of a GameServerSet
-type
+replicas
-
-FleetAutoscalerPolicyType
-
+int32
|
- Type of autoscaling policy. +Replicas is the total number of current GameServer replicas |
-buffer
+readyReplicas
-
-BufferPolicy
-
+int32
|
-(Optional)
- Buffer policy config params. Present only if FleetAutoscalerPolicyType = Buffer. +ReadyReplicas is the number of Ready GameServer replicas |
-webhook
+reservedReplicas
-
-WebhookPolicy
-
+int32
|
-(Optional)
- Webhook policy config params. Present only if FleetAutoscalerPolicyType = Webhook. +ReservedReplicas is the number of Reserved GameServer replicas |
-counter
+allocatedReplicas
-
-CounterPolicy
-
+int32
|
-(Optional)
- [Stage:Alpha] -[FeatureFlag:CountsAndLists] -Counter policy config params. Present only if FleetAutoscalerPolicyType = Counter. +AllocatedReplicas is the number of Allocated GameServer replicas |
-list
+shutdownReplicas
-
-ListPolicy
-
+int32
|
-(Optional)
- [Stage:Alpha] -[FeatureFlag:CountsAndLists] -List policy config params. Present only if FleetAutoscalerPolicyType = List. +ShutdownReplicas is the number of Shutdown GameServers replicas |
string
alias)-(Appears on: -FleetAutoscalerPolicy) -
--
FleetAutoscalerPolicyType is the policy for autoscaling -for a given Fleet
- --(Appears on: -FleetAutoscaler) -
--
FleetAutoscalerSpec is the spec for a Fleet Scaler
- -Field | -Description | -
---|---|
-fleetName
+players
-string
+
+AggregatedPlayerStatus
+
|
+(Optional)
+ [Stage:Alpha] +[FeatureFlag:PlayerTracking] +Players is the current total player capacity and count for this GameServerSet |
-policy
+counters
-
-FleetAutoscalerPolicy
+
+map[string]agones.dev/agones/pkg/apis/agones/v1.AggregatedCounterStatus
|
- Autoscaling policy +(Optional) +(Beta, CountsAndLists feature flag) Counters provides aggregated Counter capacity and Counter +count for this GameServerSet. |
-sync
+lists
-
-FleetAutoscalerSync
+
+map[string]agones.dev/agones/pkg/apis/agones/v1.AggregatedListStatus
|
(Optional)
- Sync defines when FleetAutoscalers runs autoscaling +(Beta, CountsAndLists feature flag) Lists provides aggregated List capacity and List values +for this GameServerSet. |
(Appears on: -FleetAutoscaler) +GameServer, +GameServerTemplateSpec)
-
FleetAutoscalerStatus defines the current status of a FleetAutoscaler
+GameServerSpec is the spec for a GameServer resource
-currentReplicas
+container
-int32
+string
|
- CurrentReplicas is the current number of gameserver replicas -of the fleet managed by this autoscaler, as last seen by the autoscaler +Container specifies which Pod container is the game server. Only required if there is more than one +container defined |
-desiredReplicas
+ports
-int32
+
+[]GameServerPort
+
|
- DesiredReplicas is the desired number of gameserver replicas -of the fleet managed by this autoscaler, as last calculated by the autoscaler +Ports are the array of ports that can be exposed via the game server |
-lastScaleTime
+health
-
-Kubernetes meta/v1.Time
+
+Health
|
-(Optional)
- lastScaleTime is the last time the FleetAutoscaler scaled the attached fleet, +Health configures health checking |
-ableToScale
+scheduling
-bool
+agones.dev/agones/pkg/apis.SchedulingStrategy
|
- AbleToScale indicates that we can access the target fleet +Scheduling strategy. Defaults to “Packed” |
-scalingLimited
+sdkServer
-bool
+
+SdkServer
+
|
- ScalingLimited indicates that the calculated scale would be above or below the range -defined by MinReplicas and MaxReplicas, and has thus been capped. +SdkServer specifies parameters for the Agones SDK Server sidecar container |
-(Appears on: -FleetAutoscalerSpec) -
--
FleetAutoscalerSync describes when to sync a fleet
- -Field | -Description | +
+template
+
+
+Kubernetes core/v1.PodTemplateSpec
+
+
+ |
+
+ Template describes the Pod that will be created for the GameServer + |
---|---|---|---|
-type
+players
-
-FleetAutoscalerSyncType
+
+PlayersSpec
|
- Type of autoscaling sync. +(Optional) +(Alpha, PlayerTracking feature flag) Players provides the configuration for player tracking features. |
||
-fixedInterval
+counters
-
-FixedIntervalSync
+
+map[string]agones.dev/agones/pkg/apis/agones/v1.CounterStatus
|
(Optional)
- FixedInterval config params. Present only if FleetAutoscalerSyncType = FixedInterval. +(Beta, CountsAndLists feature flag) Counters provides the configuration for tracking of int64 values against a GameServer. +Keys must be declared at GameServer creation time. |
string
alias)-(Appears on: -FleetAutoscalerSync) -
--
FleetAutoscalerSyncType is the sync strategy for a given Fleet
- -lists
+
+
+map[string]agones.dev/agones/pkg/apis/agones/v1.ListStatus
+
+
+(Beta, CountsAndLists feature flag) Lists provides the configuration for tracking of lists of up to 1000 values against a GameServer. +Keys must be declared at GameServer creation time.
+eviction
+
+
+Eviction
+
+
+Eviction specifies the eviction tolerance of the GameServer. Defaults to “Never”.
+string
alias)+(Appears on: +GameServerSelector, +GameServerStatus) +
++
GameServerState is the state for the GameServer
+ +(Appears on: -FleetAutoscalerPolicy) +GameServer)
-
ListPolicy controls the desired behavior of the List autoscaler policy.
+GameServerStatus is the status for a GameServer resource
-key
+state
+
+
+GameServerState
+
+
+ |
+
+ GameServerState is the current state of a GameServer, e.g. Creating, Starting, Ready, etc + |
+
+ports
+
+
+[]GameServerStatusPort
+
+
+ |
++ | +
+address
string
|
- Key is the name of the List. Required field. |
-maxCapacity
+addresses
-int64
+
+[]Kubernetes core/v1.NodeAddress
+
|
- MaxCapacity is the maximum aggregate List total capacity across the fleet. -MaxCapacity must be bigger than both MinCapacity and BufferSize. Required field. +(Optional) +Addresses is the array of addresses at which the GameServer can be reached; copy of Node.Status.addresses. + |
+
+nodeName
+
+string
+
+ |
++ | +
+reservedUntil
+
+
+Kubernetes meta/v1.Time
+
+
+ |
++ | +
+players
+
+
+PlayerStatus
+
+
+ |
+
+(Optional)
+ [Stage:Alpha] +[FeatureFlag:PlayerTracking] + |
+
+counters
+
+
+map[string]agones.dev/agones/pkg/apis/agones/v1.CounterStatus
+
+
+ |
+
+(Optional)
+ (Beta, CountsAndLists feature flag) Counters and Lists provides the configuration for generic tracking features. + |
+
+lists
+
+
+map[string]agones.dev/agones/pkg/apis/agones/v1.ListStatus
+
+
+ |
++(Optional) + | +
+eviction
+
+
+Eviction
+
+
+ |
+
+(Optional)
+ Eviction specifies the eviction tolerance of the GameServer. + |
+
+(Appears on: +GameServerAllocationStatus, +GameServerStatus) +
++
GameServerStatusPort shows the port that was allocated to a +GameServer.
+ +Field | +Description | +
---|---|
+name
+
+string
+
+ |
++ | +
+port
+
+int32
+
+ |
++ | +
+(Appears on: +FleetSpec, +GameServerSetSpec) +
++
GameServerTemplateSpec is a template for GameServers
+ +Field | +Description | +||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
+metadata
+
+
+Kubernetes meta/v1.ObjectMeta
+
+
+ |
+
+Refer to the Kubernetes API documentation for the fields of the
+metadata field.
+ |
+||||||||||||||||||||||
+spec
+
+
+GameServerSpec
+
+
+ |
+
+ + +
WebhookPolicy ---(Appears on: -FleetAutoscalerPolicy) - -- WebhookPolicy controls the desired behavior of the webhook policy. -It contains the description of the webhook autoscaler service -used to form url which is accessible inside the cluster - -
|
-
Package v1 is the v1 version of the API.
+(Appears on: +GameServerSpec) -Resource Types: - --
GameServerAllocationPolicy is the Schema for the gameserverallocationpolicies API
+Health configures health checking on the GameServer
-apiVersion
-string |
-
-
-multicluster.agones.dev/v1
-
+disabled
+
+bool
+
|
-||||||||
-kind
-string
+Disabled is whether health checking is disabled or not |
-GameServerAllocationPolicy |
||||||||
-metadata
+periodSeconds
-
-Kubernetes meta/v1.ObjectMeta
-
+int32
|
-Refer to the Kubernetes API documentation for the fields of the
-metadata field.
+PeriodSeconds is the number of seconds each health ping has to occur in |
||||||||
-spec
+failureThreshold
-
-GameServerAllocationPolicySpec
-
+int32
|
- - -
ListStatus +++(Appears on: +GameServerAllocationStatus, +GameServerSpec, +GameServerStatus) + ++ ListStatus stores the current list values and maximum capacity + +
|
-
(Appears on: -GameServerAllocationPolicySpec) +GameServerStatus)
-
ClusterConnectionInfo defines the connection information for a cluster
+PlayerStatus stores the current player capacity values
-clusterName
+count
-string
+int64
|
- Optional: the name of the targeted cluster |
-allocationEndpoints
+capacity
-[]string
+int64
|
- The endpoints for the allocator service in the targeted cluster. -If the AllocationEndpoints is not set, the allocation happens on local cluster. -If there are multiple endpoints any of the endpoints that can handle allocation request should suffice |
-secretName
+ids
-string
+[]string
|
- The name of the secret that contains TLS client certificates to connect the allocator server in the targeted cluster |
+(Appears on: +GameServerSpec) +
++
PlayersSpec tracks the initial player capacity
+ +
-namespace
-
-string
-
- |
-
- The cluster namespace from which to allocate gameservers - |
+Field | +Description |
---|---|---|---|
-serverCa
+initialCapacity
-[]byte
+int64
|
- The PEM encoded server CA, used by the allocator client to authenticate the remote server. |
string
alias)+(Appears on: +GameServerPort) +
++
PortPolicy is the port policy for the GameServer
+ +-
ConnectionInfoIterator an iterator on ClusterConnectionInfo
+(Appears on: +FleetSpec, +GameServerAllocationSpec, +GameServerSetSpec) + ++
Priority is a sorting option for GameServers with Counters or Lists based on the available capacity, +i.e. the current Capacity value, minus either the Count value or List length.
-currPriority
-
-int
-
- |
-
- currPriority Current priority index from the orderedPriorities - |
-
-orderedPriorities
+type
-[]int32
+string
|
- orderedPriorities list of ordered priorities +Type: Sort by a “Counter” or a “List”. |
-priorityToCluster
+key
-map[int32]map[string][]*agones.dev/agones/pkg/apis/multicluster/v1.GameServerAllocationPolicy
+string
|
- priorityToCluster Map of priority to cluster-policies map +Key: The name of the Counter or List. If not found on the GameServer, has no impact. |
-clusterBlackList
+order
-map[string]bool
+string
|
- clusterBlackList the cluster blacklist for the clusters that has already returned +Order: Sort by “Ascending” or “Descending”. “Descending” a bigger available capacity is preferred. +“Ascending” would be smaller available capacity is preferred. +The default sort order is “Ascending” |
(Appears on: -GameServerAllocationPolicy) +GameServerSpec)
-
GameServerAllocationPolicySpec defines the desired state of GameServerAllocationPolicy
+SdkServer specifies parameters for the Agones SDK Server sidecar container
-priority
+logLevel
-int32
+
+SdkServerLogLevel
+
|
+ LogLevel for SDK server (sidecar) logs. Defaults to “Info” |
-weight
+grpcPort
-int
+int32
|
+ GRPCPort is the port on which the SDK Server binds the gRPC server to accept incoming connections |
-connectionInfo
+httpPort
-
-ClusterConnectionInfo
-
+int32
|
+ HTTPPort is the port on which the SDK Server binds the HTTP gRPC gateway server to accept incoming connections |
string
alias)+(Appears on: +SdkServer) +
++
SdkServerLogLevel is the log level for SDK server (sidecar) logs
+
Package v1 is the v1 version of the API.
Resource Types: --
Fleet is the data structure for a Fleet resource
+GameServerAllocation is the data structure for allocating against a set of
+GameServers, defined selectors
selectors
-agones.dev/v1
+allocation.agones.dev/v1
|
@@ -2246,7 +2255,7 @@ Fleet |
+GameServerAllocation |
||||||||||||||||
@@ -2266,8 +2275,8 @@ Fleet
spec
-
-FleetSpec
+
+GameServerAllocationSpec
Fleet
status
-
-FleetStatus
+
+GameServerAllocationStatus
|
+(Appears on: +GameServerAllocationSpec) +
++
CounterAction is an optional action that can be performed on a Counter at allocation.
+ +Field | +Description | +
---|---|
+action
+
+string
+
+ |
+
+(Optional)
+ Action must to either “Increment” or “Decrement” the Counter’s Count. Must also define the Amount. + |
+
+amount
+
+int64
+
+ |
+
+(Optional)
+ Amount is the amount to increment or decrement the Count. Must be a positive integer. + |
+
+capacity
+
+int64
+
+ |
+
+(Optional)
+ Capacity is the amount to update the maximum capacity of the Counter to this number. Min 0, Max int64. + |
+
-
GameServer is the data structure for a GameServer resource.
-It is worth noting that while there is a GameServerStatus
Status entry for the GameServer
, it is not
-defined as a subresource - unlike Fleet
and other Agones resources.
-This is so that we can retain the ability to change multiple aspects of a GameServer
in a single atomic operation,
-which is particularly useful for operations such as allocation.
+
CounterSelector is the filter options for a GameServer based on the count and/or available capacity.
-apiVersion
-string |
-
-
-agones.dev/v1
-
- |
-||||||||||||||||||||||
-kind
-string
- |
-GameServer |
-||||||||||||||||||||||
-metadata
+minCount
-
-Kubernetes meta/v1.ObjectMeta
-
+int64
|
-Refer to the Kubernetes API documentation for the fields of the
-metadata field.
+(Optional)
+MinCount is the minimum current value. Defaults to 0. |
||||||||||||||||||||||
-spec
+maxCount
-
-GameServerSpec
-
+int64
|
- - -
GameServerAllocationSpec +++(Appears on: +GameServerAllocation) + ++ GameServerAllocationSpec is the spec for a GameServerAllocation + +
[Stage: Beta] +[FeatureFlag:CountsAndLists] +Counter actions to perform during allocation. |
||||||||||||||||||||||
-status
+lists
-
-GameServerStatus
+
+map[string]agones.dev/agones/pkg/apis/allocation/v1.ListAction
|
+(Optional)
+ [Stage: Beta] +[FeatureFlag:CountsAndLists] +List actions to perform during allocation. |
string
alias)+(Appears on: +GameServerAllocationStatus) +
++
GameServerAllocationState is the Allocation state
+ +-
GameServerSet is the data structure for a set of GameServers. -This matches philosophically with the relationship between -Deployments and ReplicaSets
+(Appears on: +GameServerAllocation) + ++
GameServerAllocationStatus is the status for an GameServerAllocation resource
-apiVersion
-string |
+
-
-agones.dev/v1
-
+GameServerState is the current state of an GameServerAllocation, e.g. Allocated, or UnAllocated |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
-kind
+gameServerName
+
string
+
+ |
+- | GameServerSet |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
-metadata
+ports
-
-Kubernetes meta/v1.ObjectMeta
+
+[]GameServerStatusPort
|
-Refer to the Kubernetes API documentation for the fields of the
-metadata field.
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
-spec
+address
-
-GameServerSetSpec
+string
+
+ |
++ | +|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
+addresses
+
+
+[]Kubernetes core/v1.NodeAddress
|
- - -
GameServerMetadata +++(Appears on: +GameServerAllocationStatus) + ++ GameServerMetadata is the metadata from the allocated game server at allocation time + +
AggregatedCounterStatus
+ |
-allocatedCount
+LabelSelector
-int64
+
+Kubernetes meta/v1.LabelSelector
+
|
+
+(Members of See: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ |
-allocatedCapacity
+gameServerState
-int64
+
+GameServerState
+
|
+ GameServerState specifies which State is the filter to be used when attempting to retrieve a GameServer +via Allocation. Defaults to “Ready”. The only other option is “Allocated”, which can be used in conjunction with +label/annotation/player selectors to retrieve an already Allocated GameServer. |
-count
+players
-int64
+
+PlayerSelector
+
|
+(Optional)
+ [Stage:Alpha] +[FeatureFlag:PlayerAllocationFilter] +Players provides a filter on minimum and maximum values for player capacity when retrieving a GameServer +through Allocation. Defaults to no limits. |
-capacity
+counters
-int64
+
+map[string]agones.dev/agones/pkg/apis/allocation/v1.CounterSelector
+
+
+ |
+
+(Optional)
+ [Stage: Beta] +[FeatureFlag:CountsAndLists] +Counters provides filters on minimum and maximum values +for a Counter’s count and available capacity when retrieving a GameServer through Allocation. +Defaults to no limits. + |
+
+lists
+
+
+map[string]agones.dev/agones/pkg/apis/allocation/v1.ListSelector
+
|
+(Optional)
+ [Stage: Beta] +[FeatureFlag:CountsAndLists] +Lists provides filters on minimum and maximum values +for List capacity, and for the existence of a value in a List, when retrieving a GameServer +through Allocation. Defaults to no limits. |
(Appears on: -FleetStatus, -GameServerSetStatus) +GameServerAllocationSpec)
-
AggregatedListStatus stores total and allocated List tracking values
+ListAction is an optional action that can be performed on a List at allocation.
-allocatedCount
-
-int64
-
- |
-- | -
-allocatedCapacity
-
-int64
-
- |
-- | -
-count
+addValues
-int64
+[]string
|
+(Optional)
+ AddValues appends values to a List’s Values array. Any duplicate values will be ignored. |
+(Optional)
+ Capacity updates the maximum capacity of the Counter to this number. Min 0, Max 1000. |
(Appears on: -FleetStatus, -GameServerSetStatus) +GameServerSelector)
-
AggregatedPlayerStatus stores total player tracking values
+ListSelector is the filter options for a GameServer based on List available capacity and/or the +existence of a value in a List.
-count
+containsValue
+
+string
+
+ |
+
+(Optional)
+ ContainsValue says to only match GameServers who has this value in the list. Defaults to “”, which is all. + |
+
+minAvailable
int64
|
+(Optional)
+ MinAvailable specifies the minimum capacity (current capacity - current count) available on a GameServer. Defaults to 0. |
-capacity
+maxAvailable
int64
|
+(Optional)
+ MaxAvailable specifies the maximum capacity (current capacity - current count) available on a GameServer. Defaults to 0, which is translated as max(int64). |
(Appears on: -FleetSpec, -GameServerSetSpec) +GameServerAllocationSpec)
-
AllocationOverflow specifies what labels and/or annotations to apply on Allocated GameServers
-if the desired number of the underlying GameServerSet
drops below the number of Allocated GameServers
-attached to it.
MetaPatch is the metadata used to patch the GameServer metadata on allocation
-(Optional)
- Labels to be applied to the |
-(Optional)
- Annotations to be applied to the |
(Appears on: -GameServerAllocationStatus, -GameServerSpec, -GameServerStatus) +GameServerAllocationSpec)
-
CounterStatus stores the current counter values and maximum capacity
+MultiClusterSetting specifies settings for multi-cluster allocation.
-count
+enabled
-int64
+bool
|
@@ -2971,9 +3177,11 @@ CounterStatus |
-capacity
+policySelector
-int64
+
+Kubernetes meta/v1.LabelSelector
+
|
@@ -2981,15 +3189,14 @@ CounterStatus |
(Appears on: -GameServerSpec, -GameServerStatus) +GameServerSelector)
-
Eviction specifies the eviction tolerance of the GameServer
+PlayerSelector is the filter options for a GameServer based on player counts
-safe
+minAvailable
+
+int64
+
+ |
++ | +
+maxAvailable
-
-EvictionSafe
-
+int64
|
- Game server supports termination via SIGTERM: -- Always: Allow eviction for both Cluster Autoscaler and node drain for upgrades -- OnUpgrade: Allow eviction for upgrades alone -- Never (default): Pod should run to completion |
string
alias)-(Appears on: -Eviction) -
+-
EvictionSafe specified whether the game server supports termination via SIGTERM
+Package v1 is the v1 version of the API.
--(Appears on: -Fleet) -
--
FleetSpec is the spec for a Fleet
+FleetAutoscaler is the data structure for a FleetAutoscaler resource
-replicas
-
-int32
-
+apiVersion
+string |
+
+
+autoscaling.agones.dev/v1
+
|
+||||||
- Replicas are the number of GameServers that should be in this set. Defaults to 0. +kind
+string
|
+FleetAutoscaler |
||||||
-allocationOverflow
+metadata
-
-AllocationOverflow
+
+Kubernetes meta/v1.ObjectMeta
|
-(Optional)
- Labels and/or Annotations to apply to overflowing GameServers when the number of Allocated GameServers is more
-than the desired replicas on the underlying metadata field.
|
||||||
-strategy
+spec
-
-Kubernetes apps/v1.DeploymentStrategy
+
+FleetAutoscalerSpec
|
- Deployment strategy ++ +
|
||||||
-template
+status
-
-GameServerTemplateSpec
+
+FleetAutoscalerStatus
|
- Template the GameServer template to apply for this Fleet |
(Appears on: -Fleet, -FleetAutoscaleRequest) +Schedule)
-
FleetStatus is the status of a Fleet
+ActivePeriod defines the time period that the policy is applied.
-replicas
-
-int32
-
- |
-
- Replicas the total number of current GameServer replicas - |
-
-readyReplicas
+timezone
-int32
+string
|
- ReadyReplicas are the number of Ready GameServer replicas +Timezone to be used for the startCron field. If not set, startCron is defaulted to the UTC timezone. |
-reservedReplicas
+startCron
-int32
+string
|
- ReservedReplicas are the total number of Reserved GameServer replicas in this fleet. -Reserved instances won’t be deleted on scale down, but won’t cause an autoscaler to scale up. +StartCron defines when the policy should be applied. +If not set, the policy is always to be applied within the start and end time. +This field must conform to UNIX cron syntax. |
-allocatedReplicas
+duration
-int32
+string
|
- AllocatedReplicas are the number of Allocated GameServer replicas +The representation limits the largest representable duration to approximately 290 years. +Valid time units are “ns”, “us” (or “µs”), “ms”, “s”, “m”, “h”. |
+(Appears on: +Schedule) +
++
Between defines the time period that the policy is eligible to be applied.
+ +
-players
-
-
-AggregatedPlayerStatus
-
-
- |
-
-(Optional)
- [Stage:Alpha] -[FeatureFlag:PlayerTracking] -Players are the current total player capacity and count for this Fleet - |
+Field | +Description |
---|---|---|---|
-counters
+start
-
-map[string]agones.dev/agones/pkg/apis/agones/v1.AggregatedCounterStatus
-
+string
|
-(Optional)
- (Alpha, CountsAndLists feature flag) Counters provides aggregated Counter capacity and Counter -count for this Fleet. +Start is the datetime that the policy is eligible to be applied. +This field must conform to RFC3339 format. If this field not set or is in the past, the policy is eligible to be applied +as soon as the fleet autoscaler is running. |
||
-lists
+end
-
-map[string]agones.dev/agones/pkg/apis/agones/v1.AggregatedListStatus
-
+string
|
-(Optional)
- (Alpha, CountsAndLists feature flag) Lists provides aggregated List capacityv and List values -for this Fleet. +End is the datetime that the policy is no longer eligible to be applied. +This field must conform to RFC3339 format. If not set, the policy is always eligible to be applied, after the start time above. |
(Appears on: -GameServerSpec) +FleetAutoscalerPolicy)
-
GameServerPort defines a set of Ports that -are to be exposed via the GameServer
+BufferPolicy controls the desired behavior of the buffer policy.
-name
+maxReplicas
-string
+int32
|
- Name is the descriptive name of the port +MaxReplicas is the maximum amount of replicas that the fleet may have. +It must be bigger than both MinReplicas and BufferSize |
-range
+minReplicas
-string
+int32
|
-(Optional)
- (Alpha, PortRanges feature flag) Range is the port range name from which to select a port when using a -‘Dynamic’ or ‘Passthrough’ port policy. +MinReplicas is the minimum amount of replicas that the fleet must have +If zero, it is ignored. +If non zero, it must be smaller than MaxReplicas and bigger than BufferSize |
-portPolicy
+bufferSize
-
-PortPolicy
-
+k8s.io/apimachinery/pkg/util/intstr.IntOrString
|
- PortPolicy defines the policy for how the HostPort is populated.
-Dynamic port will allocate a HostPort within the selected MIN_PORT and MAX_PORT range passed to the controller
-at installation time.
-When BufferSize defines how many replicas the autoscaler tries to have ready all the time +Value can be an absolute number (ex: 5) or a percentage of desired gs instances (ex: 15%) +Absolute number is calculated from percentage by rounding up. +Example: when this is set to 20%, the autoscaler will make sure that 20% +of the fleet’s game server replicas are ready. When this is set to 20, +the autoscaler will make sure that there are 20 available game servers +Must be bigger than 0 +Note: by “ready” we understand in this case “non-allocated”; this is done to ensure robustness +and computation stability in different edge case (fleet just created, not enough +capacity in the cluster etc) |
+
ChainEntry defines a single entry in the ChainPolicy.
+ +
-container
-
-string
-
- |
-
-(Optional)
- Container is the name of the container on which to open the port. Defaults to the game server container. - |
+Field | +Description |
---|---|---|---|
-containerPort
+id
-int32
+string
|
- ContainerPort is the port that is being opened on the specified container’s process +ID is the unique identifier for a ChainEntry. If not set the identifier will be set to the index of chain entry. |
||
-hostPort
+schedule
-int32
+
+Schedule
+
|
- HostPort the port exposed on the host for clients to connect to +Schedule defines when the policy is applied. |
||
-protocol
-
-
-Kubernetes core/v1.Protocol
+policy
+
+
+FleetAutoscalerPolicy
|
- Protocol is the network protocol being used. Defaults to UDP. TCP and TCPUDP are other options. +Policy is the name of the policy to be applied. Required field. |
[]agones.dev/agones/pkg/apis/autoscaling/v1.ChainEntry
alias)+(Appears on: +FleetAutoscalerPolicy) +
++
ChainPolicy controls the desired behavior of the Chain autoscaler policy.
+ +(Appears on: -GameServerSet) +FleetAutoscalerPolicy)
-
GameServerSetSpec the specification for GameServerSet
+CounterPolicy controls the desired behavior of the Counter autoscaler policy.
-replicas
+key
-int32
+string
|
- Replicas are the number of GameServers that should be in this set +Key is the name of the Counter. Required field. |
-allocationOverflow
+maxCapacity
-
-AllocationOverflow
-
+int64
|
-(Optional)
- Labels and Annotations to apply to GameServers when the number of Allocated GameServers drops below
-the desired replicas on the underlying MaxCapacity is the maximum aggregate Counter total capacity across the fleet. +MaxCapacity must be bigger than both MinCapacity and BufferSize. Required field. |
-scheduling
+minCapacity
-agones.dev/agones/pkg/apis.SchedulingStrategy
+int64
|
- Scheduling strategy. Defaults to “Packed”. +MinCapacity is the minimum aggregate Counter total capacity across the fleet. +If zero, MinCapacity is ignored. +If non zero, MinCapacity must be smaller than MaxCapacity and bigger than BufferSize. |
-priorities
+bufferSize
-
-[]Priority
-
+k8s.io/apimachinery/pkg/util/intstr.IntOrString
|
-(Optional)
- [Stage: Alpha]
-[FeatureFlag:CountsAndLists]
- Priority of sorting is in descending importance. I.e. The position 0 For For BufferSize is the size of a buffer of counted items that are available in the Fleet (available +capacity). Value can be an absolute number (ex: 5) or a percentage of desired gs instances +(ex: 5%). An absolute number is calculated from percentage by rounding up. +Must be bigger than 0. Required field. |
+(Appears on: +FleetAutoscalerSync) +
++
FixedIntervalSync controls the desired behavior of the fixed interval based sync.
+ +Field | +Description | +
---|---|
-template
+seconds
-
-GameServerTemplateSpec
-
+int32
|
- Template the GameServer template to apply for this GameServerSet +Seconds defines how often we run fleet autoscaling in seconds |
(Appears on: -GameServerSet) +FleetAutoscaleReview)
-
GameServerSetStatus is the status of a GameServerSet
+FleetAutoscaleRequest defines the request to webhook autoscaler endpoint
-replicas
+uid
-int32
+k8s.io/apimachinery/pkg/types.UID
|
- Replicas is the total number of current GameServer replicas +UID is an identifier for the individual request/response. It allows us to distinguish instances of requests which are +otherwise identical (parallel requests, requests when earlier requests did not modify etc) +The UID is meant to track the round trip (request/response) between the Autoscaler and the WebHook, not the user request. +It is suitable for correlating log entries between the webhook and apiserver, for either auditing or debugging. |
-readyReplicas
+name
-int32
+string
|
- ReadyReplicas is the number of Ready GameServer replicas +Name is the name of the Fleet being scaled |
-reservedReplicas
+namespace
-int32
+string
|
- ReservedReplicas is the number of Reserved GameServer replicas +Namespace is the namespace associated with the request (if any). |
-allocatedReplicas
+status
-int32
+
+FleetStatus
+
|
- AllocatedReplicas is the number of Allocated GameServer replicas +The Fleet’s status values |
+(Appears on: +FleetAutoscaleReview) +
++
FleetAutoscaleResponse defines the response of webhook autoscaler endpoint
+ +
-shutdownReplicas
-
-int32
-
- |
-
- ShutdownReplicas is the number of Shutdown GameServers replicas - |
+Field | +Description |
---|---|---|---|
-players
+uid
-
-AggregatedPlayerStatus
-
+k8s.io/apimachinery/pkg/types.UID
|
-(Optional)
- [Stage:Alpha] -[FeatureFlag:PlayerTracking] -Players is the current total player capacity and count for this GameServerSet +UID is an identifier for the individual request/response. +This should be copied over from the corresponding FleetAutoscaleRequest. |
||
-counters
+scale
-
-map[string]agones.dev/agones/pkg/apis/agones/v1.AggregatedCounterStatus
-
+bool
|
-(Optional)
- (Alpha, CountsAndLists feature flag) Counters provides aggregated Counter capacity and Counter -count for this GameServerSet. +Set to false if no scaling should occur to the Fleet |
||
-lists
+replicas
-
-map[string]agones.dev/agones/pkg/apis/agones/v1.AggregatedListStatus
-
+int32
|
-(Optional)
- (Alpha, CountsAndLists feature flag) Lists provides aggregated List capacity and List values -for this GameServerSet. +The targeted replica count |
-(Appears on: -GameServer, -GameServerTemplateSpec) -
--
GameServerSpec is the spec for a GameServer resource
+FleetAutoscaleReview is passed to the webhook with a populated Request value, +and then returned with a populated Response.
-container
-
-string
-
- |
-
- Container specifies which Pod container is the game server. Only required if there is more than one -container defined - |
-
-ports
+request
-
-[]GameServerPort
+
+FleetAutoscaleRequest
|
- Ports are the array of ports that can be exposed via the game server |
-health
+response
-
-Health
+
+FleetAutoscaleResponse
|
- Health configures health checking |
+(Appears on: +ChainEntry, +FleetAutoscalerSpec) +
++
FleetAutoscalerPolicy describes how to scale a fleet
+ +
-scheduling
-
-agones.dev/agones/pkg/apis.SchedulingStrategy
-
- |
-
- Scheduling strategy. Defaults to “Packed” - |
+Field | +Description |
---|---|---|---|
-sdkServer
+type
-
-SdkServer
+
+FleetAutoscalerPolicyType
|
- SdkServer specifies parameters for the Agones SDK Server sidecar container +Type of autoscaling policy. |
||
-template
+buffer
-
-Kubernetes core/v1.PodTemplateSpec
+
+BufferPolicy
|
- Template describes the Pod that will be created for the GameServer +(Optional) +Buffer policy config params. Present only if FleetAutoscalerPolicyType = Buffer. |
||
-players
+webhook
-
-PlayersSpec
+
+WebhookPolicy
|
(Optional)
- (Alpha, PlayerTracking feature flag) Players provides the configuration for player tracking features. +Webhook policy config params. Present only if FleetAutoscalerPolicyType = Webhook. |
||
-counters
+counter
-
-map[string]agones.dev/agones/pkg/apis/agones/v1.CounterStatus
+
+CounterPolicy
|
(Optional)
- (Alpha, CountsAndLists feature flag) Counters provides the configuration for tracking of int64 values against a GameServer. -Keys must be declared at GameServer creation time. +[Stage:Beta] +[FeatureFlag:CountsAndLists] +Counter policy config params. Present only if FleetAutoscalerPolicyType = Counter. |
||
-lists
+list
-
-map[string]agones.dev/agones/pkg/apis/agones/v1.ListStatus
+
+ListPolicy
|
(Optional)
- (Alpha, CountsAndLists feature flag) Lists provides the configuration for tracking of lists of up to 1000 values against a GameServer. -Keys must be declared at GameServer creation time. +[Stage:Beta] +[FeatureFlag:CountsAndLists] +List policy config params. Present only if FleetAutoscalerPolicyType = List. |
||
-eviction
+chain
-
-Eviction
+
+ChainPolicy
|
(Optional)
- Eviction specifies the eviction tolerance of the GameServer. Defaults to “Never”. +[Stage:Dev] +[FeatureFlag:ScheduledAutoscaler] +Chain policy config params. Present only if FleetAutoscalerPolicyType = Chain. |
string
alias)(Appears on: -GameServerSelector, -GameServerStatus) +FleetAutoscalerPolicy)
-
GameServerState is the state for the GameServer
+FleetAutoscalerPolicyType is the policy for autoscaling +for a given Fleet
-(Appears on: -GameServer) +FleetAutoscaler)
-
GameServerStatus is the status for a GameServer resource
+FleetAutoscalerSpec is the spec for a Fleet Scaler
-state
+fleetName
-
-GameServerState
-
+string
|
- GameServerState is the current state of a GameServer, e.g. Creating, Starting, Ready, etc |
-ports
+policy
-
-[]GameServerStatusPort
+
+FleetAutoscalerPolicy
|
+ Autoscaling policy |
-address
-
-string
-
- |
-- | -
-addresses
+sync
-
-[]Kubernetes core/v1.NodeAddress
+
+FleetAutoscalerSync
|
(Optional)
- Addresses is the array of addresses at which the GameServer can be reached; copy of Node.Status.addresses. +Sync defines when FleetAutoscalers runs autoscaling |
+(Appears on: +FleetAutoscaler) +
++
FleetAutoscalerStatus defines the current status of a FleetAutoscaler
+ +
-nodeName
-
-string
-
- |
-- | +Field | +Description |
---|---|---|---|
-reservedUntil
+currentReplicas
-
-Kubernetes meta/v1.Time
-
+int32
|
+ CurrentReplicas is the current number of gameserver replicas +of the fleet managed by this autoscaler, as last seen by the autoscaler |
||
-players
+desiredReplicas
-
-PlayerStatus
-
+int32
|
-(Optional)
- [Stage:Alpha] -[FeatureFlag:PlayerTracking] +DesiredReplicas is the desired number of gameserver replicas +of the fleet managed by this autoscaler, as last calculated by the autoscaler |
||
-counters
+lastScaleTime
-
-map[string]agones.dev/agones/pkg/apis/agones/v1.CounterStatus
+
+Kubernetes meta/v1.Time
|
(Optional)
- (Alpha, CountsAndLists feature flag) Counters and Lists provides the configuration for generic tracking features. +lastScaleTime is the last time the FleetAutoscaler scaled the attached fleet, |
||
-lists
+ableToScale
-
-map[string]agones.dev/agones/pkg/apis/agones/v1.ListStatus
-
+bool
|
-(Optional)
+ AbleToScale indicates that we can access the target fleet |
||
-eviction
+scalingLimited
-
-Eviction
-
+bool
|
-(Optional)
- Eviction specifies the eviction tolerance of the GameServer. +ScalingLimited indicates that the calculated scale would be above or below the range +defined by MinReplicas and MaxReplicas, and has thus been capped. |
(Appears on: -GameServerAllocationStatus, -GameServerStatus) +FleetAutoscalerSpec)
-
GameServerStatusPort shows the port that was allocated to a -GameServer.
+FleetAutoscalerSync describes when to sync a fleet
-name
+type
-string
+
+FleetAutoscalerSyncType
+
|
+ Type of autoscaling sync. |
-port
+fixedInterval
-int32
+
+FixedIntervalSync
+
|
+(Optional)
+ FixedInterval config params. Present only if FleetAutoscalerSyncType = FixedInterval. |
string
alias)+(Appears on: +FleetAutoscalerSync) +
++
FleetAutoscalerSyncType is the sync strategy for a given Fleet
+ +(Appears on: -FleetSpec, -GameServerSetSpec) +FleetAutoscalerPolicy)
-
GameServerTemplateSpec is a template for GameServers
+ListPolicy controls the desired behavior of the List autoscaler policy.
-metadata
-
-
-Kubernetes meta/v1.ObjectMeta
-
-
- |
-
-Refer to the Kubernetes API documentation for the fields of the
-metadata field.
- |
-||||||||||||||||||||||||
-spec
-
-
-GameServerSpec
-
-
- |
-
- - -
Schedule +++(Appears on: +ChainEntry) + ++ Schedule defines when the policy should be applied. + +
WebhookPolicy +++(Appears on: +FleetAutoscalerPolicy) + ++ WebhookPolicy controls the desired behavior of the webhook policy. +It contains the description of the webhook autoscaler service +used to form url which is accessible inside the cluster + +
|
-(Appears on: -GameServerSpec) +
Package v1 is the v1 version of the API.
+Resource Types: + +-
Health configures health checking on the GameServer
+GameServerAllocationPolicy is the Schema for the gameserverallocationpolicies API
-disabled
-
-bool
-
+apiVersion
+string |
+
+
+multicluster.agones.dev/v1
+
|
+
- Disabled is whether health checking is disabled or not +kind
+string
|
+GameServerAllocationPolicy |
-periodSeconds
+metadata
-int32
+
+Kubernetes meta/v1.ObjectMeta
+
|
- PeriodSeconds is the number of seconds each health ping has to occur in +Refer to the Kubernetes API documentation for the fields of the +metadata field.
|
-failureThreshold
+spec
-int32
+
+GameServerAllocationPolicySpec
+
|
- FailureThreshold how many failures in a row constitutes unhealthy - |
-
-initialDelaySeconds
+priority
int32
|
- InitialDelaySeconds initial delay before checking health |
-(Appears on: -GameServerAllocationStatus, -GameServerSpec, -GameServerStatus) -
--
ListStatus stores the current list values and maximum capacity
- -Field | -Description | -
---|---|
-capacity
+weight
-int64
+int
|
@@ -4185,24 +4425,29 @@ ListStatus |
-values
+connectionInfo
-[]string
+
+ClusterConnectionInfo
+
|
(Appears on: -GameServerStatus) +GameServerAllocationPolicySpec)
-
PlayerStatus stores the current player capacity values
+ClusterConnectionInfo defines the connection information for a cluster
-count
+clusterName
-int64
+string
|
+ Optional: the name of the targeted cluster |
-capacity
+allocationEndpoints
-int64
+[]string
|
+ The endpoints for the allocator service in the targeted cluster. +If the AllocationEndpoints is not set, the allocation happens on local cluster. +If there are multiple endpoints any of the endpoints that can handle allocation request should suffice |
-ids
+secretName
-[]string
+string
|
+ The name of the secret that contains TLS client certificates to connect the allocator server in the targeted cluster |
-(Appears on: -GameServerSpec) -
--
PlayersSpec tracks the initial player capacity
- -Field | -Description | +
+namespace
+
+string
+
+ |
+
+ The cluster namespace from which to allocate gameservers + |
---|---|---|---|
-initialCapacity
+serverCa
-int64
+[]byte
|
+ The PEM encoded server CA, used by the allocator client to authenticate the remote server. |
string
alias)-(Appears on: -GameServerPort) -
--
PortPolicy is the port policy for the GameServer
- --(Appears on: -FleetSpec, -GameServerAllocationSpec, -GameServerSetSpec) -
--
Priority is a sorting option for GameServers with Counters or Lists based on the available capacity, -i.e. the current Capacity value, minus either the Count value or List length.
+ConnectionInfoIterator an iterator on ClusterConnectionInfo
-type
+currPriority
-string
+int
|
- Type: Sort by a “Counter” or a “List”. +currPriority Current priority index from the orderedPriorities |
-key
+orderedPriorities
-string
+[]int32
|
- Key: The name of the Counter or List. If not found on the GameServer, has no impact. +orderedPriorities list of ordered priorities |
-order
+priorityToCluster
-string
+map[int32]map[string][]*agones.dev/agones/pkg/apis/multicluster/v1.GameServerAllocationPolicy
|
- Order: Sort by “Ascending” or “Descending”. “Descending” a bigger available capacity is preferred. -“Ascending” would be smaller available capacity is preferred. -The default sort order is “Ascending” +priorityToCluster Map of priority to cluster-policies map + |
+
+clusterBlackList
+
+map[string]bool
+
+ |
+
+ clusterBlackList the cluster blacklist for the clusters that has already returned |
(Appears on: -GameServerSpec) +GameServerAllocationPolicy)
-
SdkServer specifies parameters for the Agones SDK Server sidecar container
+GameServerAllocationPolicySpec defines the desired state of GameServerAllocationPolicy
-logLevel
+priority
-
-SdkServerLogLevel
-
+int32
|
- LogLevel for SDK server (sidecar) logs. Defaults to “Info” |
-grpcPort
+weight
-int32
+int
|
- GRPCPort is the port on which the SDK Server binds the gRPC server to accept incoming connections |
-httpPort
+connectionInfo
-int32
+
+ClusterConnectionInfo
+
|
- HTTPPort is the port on which the SDK Server binds the HTTP gRPC gateway server to accept incoming connections |
string
alias)-(Appears on: -SdkServer) -
--
SdkServerLogLevel is the log level for SDK server (sidecar) logs
-
Generated with gen-crd-api-reference-docs
.
Packages:
+(Appears on: +SchedulePolicy) +
++
ActivePeriod defines the time period that the policy is applied.
+ +Field | +Description | +
---|---|
+timezone
+
+string
+
+ |
+
+ Timezone to be used for the startCron field. If not set, startCron is defaulted to the UTC timezone. + |
+
+startCron
+
+string
+
+ |
+
+ StartCron defines when the policy should be applied. +If not set, the policy is always to be applied within the start and end time. +This field must conform to UNIX cron syntax. + |
+
+duration
+
+string
+
+ |
+
+ Duration is the length of time that the policy is applied. +If not set, the duration is indefinite. +A duration string is a possibly signed sequence of decimal numbers, +(e.g. “300ms”, “-1.5h” or “2h45m”). +The representation limits the largest representable duration to approximately 290 years. +Valid time units are “ns”, “us” (or “µs”), “ms”, “s”, “m”, “h”. + |
+
+(Appears on: +SchedulePolicy) +
++
Between defines the time period that the policy is eligible to be applied.
+ +Field | +Description | +
---|---|
+start
+
+
+Kubernetes meta/v1.Time
+
+
+ |
+
+ Start is the datetime that the policy is eligible to be applied. +This field must conform to RFC3339 format. If this field not set or is in the past, the policy is eligible to be applied +as soon as the fleet autoscaler is running. + |
+
+end
+
+
+Kubernetes meta/v1.Time
+
+
+ |
+
+ End is the datetime that the policy is no longer eligible to be applied. +This field must conform to RFC3339 format. If not set, the policy is always eligible to be applied, after the start time above. + |
+
@@ -7816,6 +8147,57 @@
+
ChainEntry defines a single entry in the ChainPolicy.
+ +Field | +Description | +
---|---|
+id
+
+string
+
+ |
+
+ ID is the unique identifier for a ChainEntry. If not set the identifier will be set to the index of chain entry. + |
+
+FleetAutoscalerPolicy
+
+
+FleetAutoscalerPolicy
+
+
+ |
+
+
+(Members of Policy is the name of the policy to be applied. Required field. + |
+
[]agones.dev/agones/pkg/apis/autoscaling/v1.ChainEntry
alias)+(Appears on: +FleetAutoscalerPolicy) +
++
ChainPolicy controls the desired behavior of the Chain autoscaler policy.
+@@ -8080,7 +8462,9 @@
(Appears on: -FleetAutoscalerSpec) +ChainEntry, +FleetAutoscalerSpec, +SchedulePolicy)
FleetAutoscalerPolicy describes how to scale a fleet
@@ -8166,6 +8550,38 @@schedule
+
+
+SchedulePolicy
+
+
+[Stage:Dev] +[FeatureFlag:ScheduledAutoscaler] +Schedule policy config params. Present only if FleetAutoscalerPolicyType = Schedule.
+chain
+
+
+ChainPolicy
+
+
+[Stage:Dev] +[FeatureFlag:ScheduledAutoscaler] +Chain policy config params. Present only if FleetAutoscalerPolicyType = Chain.
++(Appears on: +FleetAutoscalerPolicy) +
++
SchedulePolicy controls the desired behavior of the Schedule autoscaler policy.
+ +Field | +Description | +
---|---|
+between
+
+
+Between
+
+
+ |
+
+ Between defines the time period that the policy is eligible to be applied. + |
+
+activePeriod
+
+
+ActivePeriod
+
+
+ |
+
+ ActivePeriod defines the time period that the policy is applied. + |
+
+policy
+
+
+FleetAutoscalerPolicy
+
+
+ |
+
+ Policy is the name of the policy to be applied. Required field. + |
+
diff --git a/site/go.mod b/site/go.mod
index eddee4ec35..8d56b0112e 100644
--- a/site/go.mod
+++ b/site/go.mod
@@ -3,3 +3,8 @@ module github.com/agones/agones/site
go 1.21
require gopkg.in/yaml.v2 v2.4.0
+
+require (
+ github.com/google/docsy v0.10.0 // indirect
+ github.com/google/docsy/dependencies v0.7.2 // indirect
+)
diff --git a/site/go.sum b/site/go.sum
index dd0bc19f1f..3c9faaf83e 100644
--- a/site/go.sum
+++ b/site/go.sum
@@ -1,3 +1,11 @@
+github.com/FortAwesome/Font-Awesome v0.0.0-20230327165841-0698449d50f2/go.mod h1:IUgezN/MFpCDIlFezw3L8j83oeiIuYoj28Miwr/KUYo=
+github.com/FortAwesome/Font-Awesome v0.0.0-20240402185447-c0f460dca7f7/go.mod h1:IUgezN/MFpCDIlFezw3L8j83oeiIuYoj28Miwr/KUYo=
+github.com/google/docsy v0.10.0 h1:6tMDacPwAyRWNCfvsn/9qGOZDQ8b0aRzjRZvnZPY5dg=
+github.com/google/docsy v0.10.0/go.mod h1:c0nIAqmRTOuJ01F85U/wJPQtc3Zj9N58Kea9bOT2AJc=
+github.com/google/docsy/dependencies v0.7.2 h1:+t5ufoADQAj4XneFphz4A+UU0ICAxmNaRHVWtMYXPSI=
+github.com/google/docsy/dependencies v0.7.2/go.mod h1:gihhs5gmgeO+wuoay4FwOzob+jYJVyQbNaQOh788lD4=
+github.com/twbs/bootstrap v5.2.3+incompatible/go.mod h1:fZTSrkpSf0/HkL0IIJzvVspTt1r9zuf7XlZau8kpcY0=
+github.com/twbs/bootstrap v5.3.3+incompatible/go.mod h1:fZTSrkpSf0/HkL0IIJzvVspTt1r9zuf7XlZau8kpcY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
diff --git a/vendor/github.com/robfig/cron/v3/.gitignore b/vendor/github.com/robfig/cron/v3/.gitignore
new file mode 100644
index 0000000000..00268614f0
--- /dev/null
+++ b/vendor/github.com/robfig/cron/v3/.gitignore
@@ -0,0 +1,22 @@
+# Compiled Object files, Static and Dynamic libs (Shared Objects)
+*.o
+*.a
+*.so
+
+# Folders
+_obj
+_test
+
+# Architecture specific extensions/prefixes
+*.[568vq]
+[568vq].out
+
+*.cgo1.go
+*.cgo2.c
+_cgo_defun.c
+_cgo_gotypes.go
+_cgo_export.*
+
+_testmain.go
+
+*.exe
diff --git a/vendor/github.com/robfig/cron/v3/LICENSE b/vendor/github.com/robfig/cron/v3/LICENSE
new file mode 100644
index 0000000000..3a0f627ffe
--- /dev/null
+++ b/vendor/github.com/robfig/cron/v3/LICENSE
@@ -0,0 +1,21 @@
+Copyright (C) 2012 Rob Figueiredo
+All Rights Reserved.
+
+MIT LICENSE
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/vendor/github.com/robfig/cron/v3/README.md b/vendor/github.com/robfig/cron/v3/README.md
new file mode 100644
index 0000000000..984c537c01
--- /dev/null
+++ b/vendor/github.com/robfig/cron/v3/README.md
@@ -0,0 +1,125 @@
+[](http://godoc.org/github.com/robfig/cron)
+[](https://travis-ci.org/robfig/cron)
+
+# cron
+
+Cron V3 has been released!
+
+To download the specific tagged release, run:
+
+ go get github.com/robfig/cron/v3@v3.0.0
+
+Import it in your program as:
+
+ import "github.com/robfig/cron/v3"
+
+It requires Go 1.11 or later due to usage of Go Modules.
+
+Refer to the documentation here:
+http://godoc.org/github.com/robfig/cron
+
+The rest of this document describes the the advances in v3 and a list of
+breaking changes for users that wish to upgrade from an earlier version.
+
+## Upgrading to v3 (June 2019)
+
+cron v3 is a major upgrade to the library that addresses all outstanding bugs,
+feature requests, and rough edges. It is based on a merge of master which
+contains various fixes to issues found over the years and the v2 branch which
+contains some backwards-incompatible features like the ability to remove cron
+jobs. In addition, v3 adds support for Go Modules, cleans up rough edges like
+the timezone support, and fixes a number of bugs.
+
+New features:
+
+- Support for Go modules. Callers must now import this library as
+ `github.com/robfig/cron/v3`, instead of `gopkg.in/...`
+
+- Fixed bugs:
+ - 0f01e6b parser: fix combining of Dow and Dom (#70)
+ - dbf3220 adjust times when rolling the clock forward to handle non-existent midnight (#157)
+ - eeecf15 spec_test.go: ensure an error is returned on 0 increment (#144)
+ - 70971dc cron.Entries(): update request for snapshot to include a reply channel (#97)
+ - 1cba5e6 cron: fix: removing a job causes the next scheduled job to run too late (#206)
+
+- Standard cron spec parsing by default (first field is "minute"), with an easy
+ way to opt into the seconds field (quartz-compatible). Although, note that the
+ year field (optional in Quartz) is not supported.
+
+- Extensible, key/value logging via an interface that complies with
+ the https://github.com/go-logr/logr project.
+
+- The new Chain & JobWrapper types allow you to install "interceptors" to add
+ cross-cutting behavior like the following:
+ - Recover any panics from jobs
+ - Delay a job's execution if the previous run hasn't completed yet
+ - Skip a job's execution if the previous run hasn't completed yet
+ - Log each job's invocations
+ - Notification when jobs are completed
+
+It is backwards incompatible with both v1 and v2. These updates are required:
+
+- The v1 branch accepted an optional seconds field at the beginning of the cron
+ spec. This is non-standard and has led to a lot of confusion. The new default
+ parser conforms to the standard as described by [the Cron wikipedia page].
+
+ UPDATING: To retain the old behavior, construct your Cron with a custom
+ parser:
+
+ // Seconds field, required
+ cron.New(cron.WithSeconds())
+
+ // Seconds field, optional
+ cron.New(
+ cron.WithParser(
+ cron.SecondOptional | cron.Minute | cron.Hour | cron.Dom | cron.Month | cron.Dow | cron.Descriptor))
+
+- The Cron type now accepts functional options on construction rather than the
+ previous ad-hoc behavior modification mechanisms (setting a field, calling a setter).
+
+ UPDATING: Code that sets Cron.ErrorLogger or calls Cron.SetLocation must be
+ updated to provide those values on construction.
+
+- CRON_TZ is now the recommended way to specify the timezone of a single
+ schedule, which is sanctioned by the specification. The legacy "TZ=" prefix
+ will continue to be supported since it is unambiguous and easy to do so.
+
+ UPDATING: No update is required.
+
+- By default, cron will no longer recover panics in jobs that it runs.
+ Recovering can be surprising (see issue #192) and seems to be at odds with
+ typical behavior of libraries. Relatedly, the `cron.WithPanicLogger` option
+ has been removed to accommodate the more general JobWrapper type.
+
+ UPDATING: To opt into panic recovery and configure the panic logger:
+
+ cron.New(cron.WithChain(
+ cron.Recover(logger), // or use cron.DefaultLogger
+ ))
+
+- In adding support for https://github.com/go-logr/logr, `cron.WithVerboseLogger` was
+ removed, since it is duplicative with the leveled logging.
+
+ UPDATING: Callers should use `WithLogger` and specify a logger that does not
+ discard `Info` logs. For convenience, one is provided that wraps `*log.Logger`:
+
+ cron.New(
+ cron.WithLogger(cron.VerbosePrintfLogger(logger)))
+
+
+### Background - Cron spec format
+
+There are two cron spec formats in common usage:
+
+- The "standard" cron format, described on [the Cron wikipedia page] and used by
+ the cron Linux system utility.
+
+- The cron format used by [the Quartz Scheduler], commonly used for scheduled
+ jobs in Java software
+
+[the Cron wikipedia page]: https://en.wikipedia.org/wiki/Cron
+[the Quartz Scheduler]: http://www.quartz-scheduler.org/documentation/quartz-2.3.0/tutorials/tutorial-lesson-06.html
+
+The original version of this package included an optional "seconds" field, which
+made it incompatible with both of these formats. Now, the "standard" format is
+the default format accepted, and the Quartz format is opt-in.
diff --git a/vendor/github.com/robfig/cron/v3/chain.go b/vendor/github.com/robfig/cron/v3/chain.go
new file mode 100644
index 0000000000..9565b418e0
--- /dev/null
+++ b/vendor/github.com/robfig/cron/v3/chain.go
@@ -0,0 +1,92 @@
+package cron
+
+import (
+ "fmt"
+ "runtime"
+ "sync"
+ "time"
+)
+
+// JobWrapper decorates the given Job with some behavior.
+type JobWrapper func(Job) Job
+
+// Chain is a sequence of JobWrappers that decorates submitted jobs with
+// cross-cutting behaviors like logging or synchronization.
+type Chain struct {
+ wrappers []JobWrapper
+}
+
+// NewChain returns a Chain consisting of the given JobWrappers.
+func NewChain(c ...JobWrapper) Chain {
+ return Chain{c}
+}
+
+// Then decorates the given job with all JobWrappers in the chain.
+//
+// This:
+// NewChain(m1, m2, m3).Then(job)
+// is equivalent to:
+// m1(m2(m3(job)))
+func (c Chain) Then(j Job) Job {
+ for i := range c.wrappers {
+ j = c.wrappers[len(c.wrappers)-i-1](j)
+ }
+ return j
+}
+
+// Recover panics in wrapped jobs and log them with the provided logger.
+func Recover(logger Logger) JobWrapper {
+ return func(j Job) Job {
+ return FuncJob(func() {
+ defer func() {
+ if r := recover(); r != nil {
+ const size = 64 << 10
+ buf := make([]byte, size)
+ buf = buf[:runtime.Stack(buf, false)]
+ err, ok := r.(error)
+ if !ok {
+ err = fmt.Errorf("%v", r)
+ }
+ logger.Error(err, "panic", "stack", "...\n"+string(buf))
+ }
+ }()
+ j.Run()
+ })
+ }
+}
+
+// DelayIfStillRunning serializes jobs, delaying subsequent runs until the
+// previous one is complete. Jobs running after a delay of more than a minute
+// have the delay logged at Info.
+func DelayIfStillRunning(logger Logger) JobWrapper {
+ return func(j Job) Job {
+ var mu sync.Mutex
+ return FuncJob(func() {
+ start := time.Now()
+ mu.Lock()
+ defer mu.Unlock()
+ if dur := time.Since(start); dur > time.Minute {
+ logger.Info("delay", "duration", dur)
+ }
+ j.Run()
+ })
+ }
+}
+
+// SkipIfStillRunning skips an invocation of the Job if a previous invocation is
+// still running. It logs skips to the given logger at Info level.
+func SkipIfStillRunning(logger Logger) JobWrapper {
+ return func(j Job) Job {
+ var ch = make(chan struct{}, 1)
+ ch <- struct{}{}
+ return FuncJob(func() {
+ select {
+ case v := <-ch:
+ j.Run()
+ ch <- v
+ default:
+ logger.Info("skip")
+ }
+ })
+ }
+}
diff --git a/vendor/github.com/robfig/cron/v3/constantdelay.go b/vendor/github.com/robfig/cron/v3/constantdelay.go
new file mode 100644
index 0000000000..cd6e7b1be9
--- /dev/null
+++ b/vendor/github.com/robfig/cron/v3/constantdelay.go
@@ -0,0 +1,27 @@
+package cron
+
+import "time"
+
+// ConstantDelaySchedule represents a simple recurring duty cycle, e.g. "Every 5 minutes".
+// It does not support jobs more frequent than once a second.
+type ConstantDelaySchedule struct {
+ Delay time.Duration
+}
+
+// Every returns a crontab Schedule that activates once every duration.
+// Delays of less than a second are not supported (will round up to 1 second).
+// Any fields less than a Second are truncated.
+func Every(duration time.Duration) ConstantDelaySchedule {
+ if duration < time.Second {
+ duration = time.Second
+ }
+ return ConstantDelaySchedule{
+ Delay: duration - time.Duration(duration.Nanoseconds())%time.Second,
+ }
+}
+
+// Next returns the next time this should be run.
+// This rounds so that the next activation time will be on the second.
+func (schedule ConstantDelaySchedule) Next(t time.Time) time.Time {
+ return t.Add(schedule.Delay - time.Duration(t.Nanosecond())*time.Nanosecond)
+}
diff --git a/vendor/github.com/robfig/cron/v3/cron.go b/vendor/github.com/robfig/cron/v3/cron.go
new file mode 100644
index 0000000000..c7e9176658
--- /dev/null
+++ b/vendor/github.com/robfig/cron/v3/cron.go
@@ -0,0 +1,355 @@
+package cron
+
+import (
+ "context"
+ "sort"
+ "sync"
+ "time"
+)
+
+// Cron keeps track of any number of entries, invoking the associated func as
+// specified by the schedule. It may be started, stopped, and the entries may
+// be inspected while running.
+type Cron struct {
+ entries []*Entry
+ chain Chain
+ stop chan struct{}
+ add chan *Entry
+ remove chan EntryID
+ snapshot chan chan []Entry
+ running bool
+ logger Logger
+ runningMu sync.Mutex
+ location *time.Location
+ parser ScheduleParser
+ nextID EntryID
+ jobWaiter sync.WaitGroup
+}
+
+// ScheduleParser is an interface for schedule spec parsers that return a Schedule
+type ScheduleParser interface {
+ Parse(spec string) (Schedule, error)
+}
+
+// Job is an interface for submitted cron jobs.
+type Job interface {
+ Run()
+}
+
+// Schedule describes a job's duty cycle.
+type Schedule interface {
+ // Next returns the next activation time, later than the given time.
+ // Next is invoked initially, and then each time the job is run.
+ Next(time.Time) time.Time
+}
+
+// EntryID identifies an entry within a Cron instance
+type EntryID int
+
+// Entry consists of a schedule and the func to execute on that schedule.
+type Entry struct {
+ // ID is the cron-assigned ID of this entry, which may be used to look up a
+ // snapshot or remove it.
+ ID EntryID
+
+ // Schedule on which this job should be run.
+ Schedule Schedule
+
+ // Next time the job will run, or the zero time if Cron has not been
+ // started or this entry's schedule is unsatisfiable
+ Next time.Time
+
+ // Prev is the last time this job was run, or the zero time if never.
+ Prev time.Time
+
+ // WrappedJob is the thing to run when the Schedule is activated.
+ WrappedJob Job
+
+ // Job is the thing that was submitted to cron.
+ // It is kept around so that user code that needs to get at the job later,
+ // e.g. via Entries() can do so.
+ Job Job
+}
+
+// Valid returns true if this is not the zero entry.
+func (e Entry) Valid() bool { return e.ID != 0 }
+
+// byTime is a wrapper for sorting the entry array by time
+// (with zero time at the end).
+type byTime []*Entry
+
+func (s byTime) Len() int { return len(s) }
+func (s byTime) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
+func (s byTime) Less(i, j int) bool {
+ // Two zero times should return false.
+ // Otherwise, zero is "greater" than any other time.
+ // (To sort it at the end of the list.)
+ if s[i].Next.IsZero() {
+ return false
+ }
+ if s[j].Next.IsZero() {
+ return true
+ }
+ return s[i].Next.Before(s[j].Next)
+}
+
+// New returns a new Cron job runner, modified by the given options.
+//
+// Available Settings
+//
+// Time Zone
+// Description: The time zone in which schedules are interpreted
+// Default: time.Local
+//
+// Parser
+// Description: Parser converts cron spec strings into cron.Schedules.
+// Default: Accepts this spec: https://en.wikipedia.org/wiki/Cron
+//
+// Chain
+// Description: Wrap submitted jobs to customize behavior.
+// Default: A chain that recovers panics and logs them to stderr.
+//
+// See "cron.With*" to modify the default behavior.
+func New(opts ...Option) *Cron {
+ c := &Cron{
+ entries: nil,
+ chain: NewChain(),
+ add: make(chan *Entry),
+ stop: make(chan struct{}),
+ snapshot: make(chan chan []Entry),
+ remove: make(chan EntryID),
+ running: false,
+ runningMu: sync.Mutex{},
+ logger: DefaultLogger,
+ location: time.Local,
+ parser: standardParser,
+ }
+ for _, opt := range opts {
+ opt(c)
+ }
+ return c
+}
+
+// FuncJob is a wrapper that turns a func() into a cron.Job
+type FuncJob func()
+
+func (f FuncJob) Run() { f() }
+
+// AddFunc adds a func to the Cron to be run on the given schedule.
+// The spec is parsed using the time zone of this Cron instance as the default.
+// An opaque ID is returned that can be used to later remove it.
+func (c *Cron) AddFunc(spec string, cmd func()) (EntryID, error) {
+ return c.AddJob(spec, FuncJob(cmd))
+}
+
+// AddJob adds a Job to the Cron to be run on the given schedule.
+// The spec is parsed using the time zone of this Cron instance as the default.
+// An opaque ID is returned that can be used to later remove it.
+func (c *Cron) AddJob(spec string, cmd Job) (EntryID, error) {
+ schedule, err := c.parser.Parse(spec)
+ if err != nil {
+ return 0, err
+ }
+ return c.Schedule(schedule, cmd), nil
+}
+
+// Schedule adds a Job to the Cron to be run on the given schedule.
+// The job is wrapped with the configured Chain.
+func (c *Cron) Schedule(schedule Schedule, cmd Job) EntryID {
+ c.runningMu.Lock()
+ defer c.runningMu.Unlock()
+ c.nextID++
+ entry := &Entry{
+ ID: c.nextID,
+ Schedule: schedule,
+ WrappedJob: c.chain.Then(cmd),
+ Job: cmd,
+ }
+ if !c.running {
+ c.entries = append(c.entries, entry)
+ } else {
+ c.add <- entry
+ }
+ return entry.ID
+}
+
+// Entries returns a snapshot of the cron entries.
+func (c *Cron) Entries() []Entry {
+ c.runningMu.Lock()
+ defer c.runningMu.Unlock()
+ if c.running {
+ replyChan := make(chan []Entry, 1)
+ c.snapshot <- replyChan
+ return <-replyChan
+ }
+ return c.entrySnapshot()
+}
+
+// Location gets the time zone location
+func (c *Cron) Location() *time.Location {
+ return c.location
+}
+
+// Entry returns a snapshot of the given entry, or nil if it couldn't be found.
+func (c *Cron) Entry(id EntryID) Entry {
+ for _, entry := range c.Entries() {
+ if id == entry.ID {
+ return entry
+ }
+ }
+ return Entry{}
+}
+
+// Remove an entry from being run in the future.
+func (c *Cron) Remove(id EntryID) {
+ c.runningMu.Lock()
+ defer c.runningMu.Unlock()
+ if c.running {
+ c.remove <- id
+ } else {
+ c.removeEntry(id)
+ }
+}
+
+// Start the cron scheduler in its own goroutine, or no-op if already started.
+func (c *Cron) Start() {
+ c.runningMu.Lock()
+ defer c.runningMu.Unlock()
+ if c.running {
+ return
+ }
+ c.running = true
+ go c.run()
+}
+
+// Run the cron scheduler, or no-op if already running.
+func (c *Cron) Run() {
+ c.runningMu.Lock()
+ if c.running {
+ c.runningMu.Unlock()
+ return
+ }
+ c.running = true
+ c.runningMu.Unlock()
+ c.run()
+}
+
+// run the scheduler.. this is private just due to the need to synchronize
+// access to the 'running' state variable.
+func (c *Cron) run() {
+ c.logger.Info("start")
+
+ // Figure out the next activation times for each entry.
+ now := c.now()
+ for _, entry := range c.entries {
+ entry.Next = entry.Schedule.Next(now)
+ c.logger.Info("schedule", "now", now, "entry", entry.ID, "next", entry.Next)
+ }
+
+ for {
+ // Determine the next entry to run.
+ sort.Sort(byTime(c.entries))
+
+ var timer *time.Timer
+ if len(c.entries) == 0 || c.entries[0].Next.IsZero() {
+ // If there are no entries yet, just sleep - it still handles new entries
+ // and stop requests.
+ timer = time.NewTimer(100000 * time.Hour)
+ } else {
+ timer = time.NewTimer(c.entries[0].Next.Sub(now))
+ }
+
+ for {
+ select {
+ case now = <-timer.C:
+ now = now.In(c.location)
+ c.logger.Info("wake", "now", now)
+
+ // Run every entry whose next time was less than now
+ for _, e := range c.entries {
+ if e.Next.After(now) || e.Next.IsZero() {
+ break
+ }
+ c.startJob(e.WrappedJob)
+ e.Prev = e.Next
+ e.Next = e.Schedule.Next(now)
+ c.logger.Info("run", "now", now, "entry", e.ID, "next", e.Next)
+ }
+
+ case newEntry := <-c.add:
+ timer.Stop()
+ now = c.now()
+ newEntry.Next = newEntry.Schedule.Next(now)
+ c.entries = append(c.entries, newEntry)
+ c.logger.Info("added", "now", now, "entry", newEntry.ID, "next", newEntry.Next)
+
+ case replyChan := <-c.snapshot:
+ replyChan <- c.entrySnapshot()
+ continue
+
+ case <-c.stop:
+ timer.Stop()
+ c.logger.Info("stop")
+ return
+
+ case id := <-c.remove:
+ timer.Stop()
+ now = c.now()
+ c.removeEntry(id)
+ c.logger.Info("removed", "entry", id)
+ }
+
+ break
+ }
+ }
+}
+
+// startJob runs the given job in a new goroutine.
+func (c *Cron) startJob(j Job) {
+ c.jobWaiter.Add(1)
+ go func() {
+ defer c.jobWaiter.Done()
+ j.Run()
+ }()
+}
+
+// now returns current time in c location
+func (c *Cron) now() time.Time {
+ return time.Now().In(c.location)
+}
+
+// Stop stops the cron scheduler if it is running; otherwise it does nothing.
+// A context is returned so the caller can wait for running jobs to complete.
+func (c *Cron) Stop() context.Context {
+ c.runningMu.Lock()
+ defer c.runningMu.Unlock()
+ if c.running {
+ c.stop <- struct{}{}
+ c.running = false
+ }
+ ctx, cancel := context.WithCancel(context.Background())
+ go func() {
+ c.jobWaiter.Wait()
+ cancel()
+ }()
+ return ctx
+}
+
+// entrySnapshot returns a copy of the current cron entry list.
+func (c *Cron) entrySnapshot() []Entry {
+ var entries = make([]Entry, len(c.entries))
+ for i, e := range c.entries {
+ entries[i] = *e
+ }
+ return entries
+}
+
+func (c *Cron) removeEntry(id EntryID) {
+ var entries []*Entry
+ for _, e := range c.entries {
+ if e.ID != id {
+ entries = append(entries, e)
+ }
+ }
+ c.entries = entries
+}
diff --git a/vendor/github.com/robfig/cron/v3/doc.go b/vendor/github.com/robfig/cron/v3/doc.go
new file mode 100644
index 0000000000..fa5d08b4db
--- /dev/null
+++ b/vendor/github.com/robfig/cron/v3/doc.go
@@ -0,0 +1,231 @@
+/*
+Package cron implements a cron spec parser and job runner.
+
+Installation
+
+To download the specific tagged release, run:
+
+ go get github.com/robfig/cron/v3@v3.0.0
+
+Import it in your program as:
+
+ import "github.com/robfig/cron/v3"
+
+It requires Go 1.11 or later due to usage of Go Modules.
+
+Usage
+
+Callers may register Funcs to be invoked on a given schedule. Cron will run
+them in their own goroutines.
+
+ c := cron.New()
+ c.AddFunc("30 * * * *", func() { fmt.Println("Every hour on the half hour") })
+ c.AddFunc("30 3-6,20-23 * * *", func() { fmt.Println(".. in the range 3-6am, 8-11pm") })
+ c.AddFunc("CRON_TZ=Asia/Tokyo 30 04 * * *", func() { fmt.Println("Runs at 04:30 Tokyo time every day") })
+ c.AddFunc("@hourly", func() { fmt.Println("Every hour, starting an hour from now") })
+ c.AddFunc("@every 1h30m", func() { fmt.Println("Every hour thirty, starting an hour thirty from now") })
+ c.Start()
+ ..
+ // Funcs are invoked in their own goroutine, asynchronously.
+ ...
+ // Funcs may also be added to a running Cron
+ c.AddFunc("@daily", func() { fmt.Println("Every day") })
+ ..
+ // Inspect the cron job entries' next and previous run times.
+ inspect(c.Entries())
+ ..
+ c.Stop() // Stop the scheduler (does not stop any jobs already running).
+
+CRON Expression Format
+
+A cron expression represents a set of times, using 5 space-separated fields.
+
+ Field name | Mandatory? | Allowed values | Allowed special characters
+ ---------- | ---------- | -------------- | --------------------------
+ Minutes | Yes | 0-59 | * / , -
+ Hours | Yes | 0-23 | * / , -
+ Day of month | Yes | 1-31 | * / , - ?
+ Month | Yes | 1-12 or JAN-DEC | * / , -
+ Day of week | Yes | 0-6 or SUN-SAT | * / , - ?
+
+Month and Day-of-week field values are case insensitive. "SUN", "Sun", and
+"sun" are equally accepted.
+
+The specific interpretation of the format is based on the Cron Wikipedia page:
+https://en.wikipedia.org/wiki/Cron
+
+Alternative Formats
+
+Alternative Cron expression formats support other fields like seconds. You can
+implement that by creating a custom Parser as follows.
+
+ cron.New(
+ cron.WithParser(
+ cron.NewParser(
+ cron.SecondOptional | cron.Minute | cron.Hour | cron.Dom | cron.Month | cron.Dow | cron.Descriptor)))
+
+Since adding Seconds is the most common modification to the standard cron spec,
+cron provides a builtin function to do that, which is equivalent to the custom
+parser you saw earlier, except that its seconds field is REQUIRED:
+
+ cron.New(cron.WithSeconds())
+
+That emulates Quartz, the most popular alternative Cron schedule format:
+http://www.quartz-scheduler.org/documentation/quartz-2.x/tutorials/crontrigger.html
+
+Special Characters
+
+Asterisk ( * )
+
+The asterisk indicates that the cron expression will match for all values of the
+field; e.g., using an asterisk in the 5th field (month) would indicate every
+month.
+
+Slash ( / )
+
+Slashes are used to describe increments of ranges. For example 3-59/15 in the
+1st field (minutes) would indicate the 3rd minute of the hour and every 15
+minutes thereafter. The form "*\/..." is equivalent to the form "first-last/...",
+that is, an increment over the largest possible range of the field. The form
+"N/..." is accepted as meaning "N-MAX/...", that is, starting at N, use the
+increment until the end of that specific range. It does not wrap around.
+
+Comma ( , )
+
+Commas are used to separate items of a list. For example, using "MON,WED,FRI" in
+the 5th field (day of week) would mean Mondays, Wednesdays and Fridays.
+
+Hyphen ( - )
+
+Hyphens are used to define ranges. For example, 9-17 would indicate every
+hour between 9am and 5pm inclusive.
+
+Question mark ( ? )
+
+Question mark may be used instead of '*' for leaving either day-of-month or
+day-of-week blank.
+
+Predefined schedules
+
+You may use one of several pre-defined schedules in place of a cron expression.
+
+ Entry | Description | Equivalent To
+ ----- | ----------- | -------------
+ @yearly (or @annually) | Run once a year, midnight, Jan. 1st | 0 0 1 1 *
+ @monthly | Run once a month, midnight, first of month | 0 0 1 * *
+ @weekly | Run once a week, midnight between Sat/Sun | 0 0 * * 0
+ @daily (or @midnight) | Run once a day, midnight | 0 0 * * *
+ @hourly | Run once an hour, beginning of hour | 0 * * * *
+
+Intervals
+
+You may also schedule a job to execute at fixed intervals, starting at the time it's added
+or cron is run. This is supported by formatting the cron spec like this:
+
+ @every