From 1ebec5802573e4165ece0594e7d6eaae2ffc01d7 Mon Sep 17 00:00:00 2001
From: Joseph Oladeji
Date: Mon, 29 Jul 2024 14:21:32 -0400
Subject: [PATCH] feat: Add API Changes and Validation for FleetAutoscaler
Chain Policy (#3893)
* Validation for new `FleetAutoscaler` `Chain` policy
* Minor fixes to CRD for `Fleetautoscaler` `Chain` policy
---
examples/chainfleetautoscaler.yaml | 76 +-
examples/schedulefleetautoscaler.yaml | 62 +
go.mod | 1 +
go.sum | 2 +
.../crds/_fleetautoscalerpolicy.yaml | 53 +-
.../templates/crds/fleetautoscaler.yaml | 2 +-
pkg/apis/autoscaling/v1/fleetautoscaler.go | 188 +-
.../autoscaling/v1/fleetautoscaler_test.go | 237 +
.../autoscaling/v1/zz_generated.deepcopy.go | 104 +
.../autoscaling/v1/activeperiod.go | 57 +
.../autoscaling/v1/between.go | 52 +
.../autoscaling/v1/chainentry.go | 100 +
.../autoscaling/v1/fleetautoscalerpolicy.go | 28 +-
.../autoscaling/v1/schedulepolicy.go | 57 +
pkg/client/applyconfiguration/utils.go | 8 +
.../Reference/agones_crd_api_reference.html | 4038 +++++++++--------
site/go.mod | 5 +
site/go.sum | 8 +
vendor/github.com/robfig/cron/v3/.gitignore | 22 +
vendor/github.com/robfig/cron/v3/LICENSE | 21 +
vendor/github.com/robfig/cron/v3/README.md | 125 +
vendor/github.com/robfig/cron/v3/chain.go | 92 +
.../robfig/cron/v3/constantdelay.go | 27 +
vendor/github.com/robfig/cron/v3/cron.go | 355 ++
vendor/github.com/robfig/cron/v3/doc.go | 231 +
vendor/github.com/robfig/cron/v3/logger.go | 86 +
vendor/github.com/robfig/cron/v3/option.go | 45 +
vendor/github.com/robfig/cron/v3/parser.go | 434 ++
vendor/github.com/robfig/cron/v3/spec.go | 188 +
vendor/modules.txt | 3 +
30 files changed, 4858 insertions(+), 1849 deletions(-)
create mode 100644 examples/schedulefleetautoscaler.yaml
create mode 100644 pkg/client/applyconfiguration/autoscaling/v1/activeperiod.go
create mode 100644 pkg/client/applyconfiguration/autoscaling/v1/between.go
create mode 100644 pkg/client/applyconfiguration/autoscaling/v1/chainentry.go
create mode 100644 pkg/client/applyconfiguration/autoscaling/v1/schedulepolicy.go
create mode 100644 vendor/github.com/robfig/cron/v3/.gitignore
create mode 100644 vendor/github.com/robfig/cron/v3/LICENSE
create mode 100644 vendor/github.com/robfig/cron/v3/README.md
create mode 100644 vendor/github.com/robfig/cron/v3/chain.go
create mode 100644 vendor/github.com/robfig/cron/v3/constantdelay.go
create mode 100644 vendor/github.com/robfig/cron/v3/cron.go
create mode 100644 vendor/github.com/robfig/cron/v3/doc.go
create mode 100644 vendor/github.com/robfig/cron/v3/logger.go
create mode 100644 vendor/github.com/robfig/cron/v3/option.go
create mode 100644 vendor/github.com/robfig/cron/v3/parser.go
create mode 100644 vendor/github.com/robfig/cron/v3/spec.go
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:
-allocation.agones.dev/v1
+agones.dev/v1
Package v1 is the v1 version of the API.
Resource Types:
-GameServerAllocation
+Fleet
-
GameServerAllocation is the data structure for allocating against a set of
-GameServers, defined selectors
selectors
+Fleet is the data structure for a Fleet resource
@@ -47,7 +50,7 @@ GameServerAllocation
string
-allocation.agones.dev/v1
+agones.dev/v1
|
@@ -56,7 +59,7 @@ GameServerAllocation
kind
string
-GameServerAllocation |
+Fleet |
@@ -76,8 +79,8 @@
-multiClusterSetting
-
-
-MultiClusterSetting
-
-
- |
-
- MultiClusterPolicySelector if specified, multi-cluster policies are applied.
-Otherwise, allocation will happen locally.
- |
-
-
-
-required
-
-
-GameServerSelector
-
-
- |
-
- 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.
- |
-
-
-
-preferred
+replicas
-
-[]GameServerSelector
-
+int32
|
- 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 required selector.
-If the first selector is not matched, the selection attempts the second selector, and so on.
-If any of the preferred selectors are matched, the required selector is not considered.
-This is useful for things like smoke testing of new game servers.
+Replicas are the number of GameServers that should be in this set. Defaults to 0.
|
-priorities
+allocationOverflow
-
-[]Priority
+
+AllocationOverflow
|
(Optional)
- [Stage: Alpha]
-[FeatureFlag:CountsAndLists]
-Priorities configuration alters the order in which GameServers are searched for matches to the configured selectors .
-Priority of sorting is in descending importance. I.e. The position 0 priority entry is checked first.
-For Packed strategy sorting, this priority list will be the tie-breaker within the least utilised infrastructure, to ensure optimal
-infrastructure usage while also allowing some custom prioritisation of GameServers .
-For Distributed strategy sorting, the entire selection of GameServers will be sorted by this priority list to provide the
-order that GameServers will be allocated by.
+Labels and/or Annotations to apply to overflowing GameServers when the number of Allocated GameServers is more
+than the desired replicas on the underlying GameServerSet
|
-selectors
+strategy
-
-[]GameServerSelector
+
+Kubernetes apps/v1.DeploymentStrategy
|
- 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.
+Deployment strategy
|
@@ -182,48 +140,36 @@ GameServerAllocation
-metadata
-
-
-MetaPatch
-
-
- |
-
- 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
- |
-
-
-
-counters
+priorities
-
-map[string]agones.dev/agones/pkg/apis/allocation/v1.CounterAction
+
+[]Priority
|
(Optional)
- [Stage: Alpha]
+ [Stage: Beta]
[FeatureFlag:CountsAndLists]
-Counter actions to perform during allocation.
+Priorities configuration alters scale down logic in Fleets based on the configured available capacity order under that key.
+Priority of sorting is in descending importance. I.e. The position 0 priority entry is checked first.
+For Packed strategy scale down, this priority list will be the tie-breaker within the node, to ensure optimal
+infrastructure usage while also allowing some custom prioritisation of GameServers .
+For Distributed strategy scale down, the entire Fleet will be sorted by this priority list to provide the
+order of GameServers to delete on scale down.
|
-lists
+template
-
-map[string]agones.dev/agones/pkg/apis/allocation/v1.ListAction
+
+GameServerTemplateSpec
|
-(Optional)
- [Stage: Alpha]
-[FeatureFlag:CountsAndLists]
-List actions to perform during allocation.
+Template the GameServer template to apply for this Fleet
|
@@ -233,8 +179,8 @@ GameServerAllocation
status
-
-GameServerAllocationStatus
+
+FleetStatus
|
@@ -243,14 +189,14 @@ GameServerAllocation
|
-CounterAction
+GameServer
-(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.
@@ -262,286 +208,204 @@ CounterAction
-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.
- |
-
-
-
-CounterSelector
-
-
-(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).
- |
-
-
-
-GameServerAllocationSpec
-
-
-(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 required selector.
-If the first selector is not matched, the selection attempts the second selector, and so on.
-If any of the preferred selectors are matched, the required selector is not considered.
-This is useful for things like smoke testing of new game servers.
+(Optional)
+(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]
-Priorities configuration alters the order in which GameServers are searched for matches to the configured selectors .
-Priority of sorting is in descending importance. I.e. The position 0 priority entry is checked first.
-For Packed strategy sorting, this priority list will be the tie-breaker within the least utilised infrastructure, to ensure optimal
-infrastructure usage while also allowing some custom prioritisation of GameServers .
-For Distributed strategy sorting, the entire selection of GameServers will be sorted by this priority list to provide the
-order that GameServers will be allocated by.
+(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
|
-(Optional)
- [Stage: Alpha]
-[FeatureFlag:CountsAndLists]
-List actions to perform during allocation.
|
-GameServerAllocationState
-(string
alias)
-
-(Appears on:
-GameServerAllocationStatus)
-
-
-
GameServerAllocationState is the Allocation state
-
-GameServerAllocationStatus
+GameServerSet
-(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
@@ -553,113 +417,128 @@ GameServerAllocatio
-state
-
-
-GameServerAllocationState
-
-
- |
+apiVersion
+string
- 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 GameServerSet
|
-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]
+Priorities configuration alters scale down logic in Fleets based on the configured available capacity order under that key.
+Priority of sorting is in descending importance. I.e. The position 0 priority entry is checked first.
+For Packed strategy scale down, this priority list will be the tie-breaker within the node, to ensure optimal
+infrastructure usage while also allowing some custom prioritisation of GameServers .
+For Distributed strategy scale down, the entire Fleet will be sorted by this priority list to provide the
+order of GameServers to delete on scale down.
|
-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
|
@@ -668,14 +547,15 @@ GameServerAllocatio
-GameServerMetadata
+AggregatedCounterStatus
(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
@@ -687,9 +567,9 @@ GameServerMetadata
-labels
+allocatedCount
-map[string]string
+int64
|
@@ -697,147 +577,82 @@ GameServerMetadata
|
-annotations
+allocatedCapacity
-map[string]string
+int64
|
|
-
-
-GameServerSelector
-
-
-(Appears on:
-GameServerAllocationSpec)
-
-
-
GameServerSelector contains all the filter options for selecting
-a GameServer for allocation.
-
-
+AggregatedListStatus
+
+
+(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.
|
-
-
-ListAction
-
-
-(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.
|
@@ -848,21 +663,19 @@ ListAction
-(Optional)
- Capacity updates the maximum capacity of the Counter to this number. Min 0, Max 1000.
|
-ListSelector
+AggregatedPlayerStatus
(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
@@ -874,50 +687,37 @@ ListSelector
-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).
|
-MetaPatch
+AllocationOverflow
(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.
@@ -935,6 +735,8 @@ MetaPatch
+(Optional)
+ Labels to be applied to the GameServer
|
@@ -945,18 +747,22 @@ MetaPatch
+(Optional)
+ Annotations to be applied to the GameServer
|
-MultiClusterSetting
+CounterStatus
(Appears on:
-GameServerAllocationSpec)
+GameServerAllocationStatus,
+GameServerSpec,
+GameServerStatus)
-
MultiClusterSetting specifies settings for multi-cluster allocation.
+CounterStatus stores the current counter values and maximum capacity
@@ -968,9 +774,9 @@ MultiClusterSetting
-enabled
+count
-bool
+int64
|
@@ -978,11 +784,9 @@ MultiClusterSetting
|
-policySelector
+capacity
-
-Kubernetes meta/v1.LabelSelector
-
+int64
|
@@ -990,14 +794,15 @@ MultiClusterSetting
|
-PlayerSelector
+Eviction
(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
@@ -1009,39 +814,39 @@ PlayerSelector
-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
|
-
-autoscaling.agones.dev/v1
+EvictionSafe
+(string
alias)
-
Package v1 is the v1 version of the API.
+(Appears on:
+Eviction)
-Resource Types:
-
-FleetAutoscaler
+
+
EvictionSafe specified whether the game server supports termination via SIGTERM
+
+FleetSpec
-
FleetAutoscaler is the data structure for a FleetAutoscaler resource
+(Appears on:
+Fleet)
+
+
+
FleetSpec is the spec for a Fleet
@@ -1053,110 +858,99 @@ FleetAutoscaler
-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 GameServerSet
|
-spec
+strategy
-
-FleetAutoscalerSpec
+
+Kubernetes apps/v1.DeploymentStrategy
|
-
-
-
-
-
-fleetName
-
-string
-
- |
-
+ Deployment strategy
|
-policy
+scheduling
-
-FleetAutoscalerPolicy
-
+agones.dev/agones/pkg/apis.SchedulingStrategy
|
- Autoscaling policy
+Scheduling strategy. Defaults to “Packed”.
|
-sync
+priorities
-
-FleetAutoscalerSync
+
+[]Priority
|
(Optional)
- Sync defines when FleetAutoscalers runs autoscaling
- |
-
-
+[Stage: Beta]
+[FeatureFlag:CountsAndLists]
+Priorities configuration alters scale down logic in Fleets based on the configured available capacity order under that key.
+Priority of sorting is in descending importance. I.e. The position 0 priority entry is checked first.
+For Packed strategy scale down, this priority list will be the tie-breaker within the node, to ensure optimal
+infrastructure usage while also allowing some custom prioritisation of GameServers .
+For Distributed strategy scale down, the entire Fleet will be sorted by this priority list to provide the
+order of GameServers to delete on scale down.
|
-status
+template
-
-FleetAutoscalerStatus
+
+GameServerTemplateSpec
|
+ Template the GameServer template to apply for this Fleet
|
-BufferPolicy
+FleetStatus
(Appears on:
-FleetAutoscalerPolicy)
+Fleet,
+FleetAutoscaleRequest)
-
BufferPolicy controls the desired behavior of the buffer policy.
+FleetStatus is the status of a Fleet
@@ -1168,128 +962,106 @@ BufferPolicy
-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.
|
-
-
-CounterPolicy
-
-
-(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.
|
-FixedIntervalSync
+GameServerPort
(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
@@ -1301,93 +1073,104 @@ FixedIntervalSync
-seconds
+name
-int32
+string
|
- Seconds defines how often we run fleet autoscaling in seconds
+Name is the descriptive name of the port
|
-
-
-FleetAutoscaleRequest
-
-
-(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 Static portPolicy is specified, HostPort is required, to specify the port that game clients will
+connect to
+Passthrough dynamically sets the containerPort to the same value as the dynamically selected hostPort.
+None portPolicy ignores HostPort and the containerPort (optional) is used to set the port on the GameServer instance.
|
-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.
|
-FleetAutoscaleResponse
+GameServerSetSpec
(Appears on:
-FleetAutoscaleReview)
+GameServerSet)
-
FleetAutoscaleResponse defines the response of webhook autoscaler endpoint
+GameServerSetSpec the specification for GameServerSet
@@ -1399,88 +1182,85 @@ FleetAutoscaleResponse
-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 GameServerSet
|
-replicas
+scheduling
-int32
+agones.dev/agones/pkg/apis.SchedulingStrategy
|
- The targeted replica count
+Scheduling strategy. Defaults to “Packed”.
|
-
-
-FleetAutoscaleReview
-
-
-
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]
+Priorities configuration alters scale down logic in Fleets based on the configured available capacity order under that key.
+Priority of sorting is in descending importance. I.e. The position 0 priority entry is checked first.
+For Packed strategy scale down, this priority list will be the tie-breaker within the node, to ensure optimal
+infrastructure usage while also allowing some custom prioritisation of GameServers .
+For Distributed strategy scale down, the entire Fleet will be sorted by this priority list to provide the
+order of GameServers to delete on scale down.
|
-response
+template
-
-FleetAutoscaleResponse
+
+GameServerTemplateSpec
|
+ Template the GameServer template to apply for this GameServerSet
|
-FleetAutoscalerPolicy
+GameServerSetStatus
(Appears on:
-FleetAutoscalerSpec)
+GameServerSet)
-
FleetAutoscalerPolicy describes how to scale a fleet
+GameServerSetStatus is the status of a GameServerSet
@@ -1492,153 +1272,116 @@ FleetAutoscalerPolicy
-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
|
-
-
-FleetAutoscalerPolicyType
-(string
alias)
-
-(Appears on:
-FleetAutoscalerPolicy)
-
-
-
FleetAutoscalerPolicyType is the policy for autoscaling
-for a given Fleet
-
-FleetAutoscalerSpec
-
-
-(Appears on:
-FleetAutoscaler)
-
-
-
FleetAutoscalerSpec is the spec for a Fleet Scaler
-
-
-FleetAutoscalerStatus
+GameServerSpec
(Appears on:
-FleetAutoscaler)
+GameServer,
+GameServerTemplateSpec)
-
FleetAutoscalerStatus defines the current status of a FleetAutoscaler
+GameServerSpec is the spec for a GameServer resource
@@ -1650,130 +1393,157 @@ FleetAutoscalerStatus
-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
|
-
-
-FleetAutoscalerSync
-
-
-(Appears on:
-FleetAutoscalerSpec)
-
-
-
FleetAutoscalerSync describes when to sync a fleet
-
-
-FleetAutoscalerSyncType
-(string
alias)
-
-(Appears on:
-FleetAutoscalerSync)
-
-
-
FleetAutoscalerSyncType is the sync strategy for a given Fleet
-
-ListPolicy
+
+
+lists
+
+
+map[string]agones.dev/agones/pkg/apis/agones/v1.ListStatus
+
+
+ |
+
+(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.
+ |
+
+
+
+eviction
+
+
+Eviction
+
+
+ |
+
+(Optional)
+ Eviction specifies the eviction tolerance of the GameServer. Defaults to “Never”.
+ |
+
+
+
+GameServerState
+(string
alias)
+
+(Appears on:
+GameServerSelector,
+GameServerStatus)
+
+
+
GameServerState is the state for the GameServer
+
+GameServerStatus
(Appears on:
-FleetAutoscalerPolicy)
+GameServer)
-
ListPolicy controls the desired behavior of the List autoscaler policy.
+GameServerStatus is the status for a GameServer resource
+GameServerStatusPort
+
+
+(Appears on:
+GameServerAllocationStatus,
+GameServerStatus)
+
+
+
GameServerStatusPort shows the port that was allocated to a
+GameServer.
+
+
+
+
+Field |
+Description |
+
+
+
+
+
+name
+
+string
+
+ |
+
+ |
+
+
+
+port
+
+int32
+
+ |
+
+ |
+
+
+
+GameServerTemplateSpec
+
+
+(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
+
+
+ |
+
+
+
+
+
+
+container
+
+string
+
+ |
+
+ Container specifies which Pod container is the game server. Only required if there is more than one
+container defined
+ |
+
+
+
+ports
+
+
+[]GameServerPort
+
+
+ |
+
+ Ports are the array of ports that can be exposed via the game server
+ |
+
+
+
+health
+
+
+Health
+
+
+ |
+
+ Health configures health checking
+ |
+
+
+
+scheduling
+
+agones.dev/agones/pkg/apis.SchedulingStrategy
+
+ |
+
+ Scheduling strategy. Defaults to “Packed”
+ |
+
+
+
+sdkServer
+
+
+SdkServer
+
+
+ |
+
+ SdkServer specifies parameters for the Agones SDK Server sidecar container
|
-minCapacity
+template
-int64
+
+Kubernetes core/v1.PodTemplateSpec
+
|
- MinCapacity is the minimum aggregate List total capacity across the fleet.
-If zero, it is ignored.
-If non zero, it must be smaller than MaxCapacity and bigger than BufferSize.
+Template describes the Pod that will be created for the GameServer
|
-bufferSize
+players
-k8s.io/apimachinery/pkg/util/intstr.IntOrString
+
+PlayersSpec
+
|
- BufferSize is the size of a buffer based on the List capacity that is available over the
-current aggregate List length in the Fleet (available capacity). It can be specified either
-as an absolute value (i.e. 5) or percentage format (i.e. 5%).
-Must be bigger than 0. Required field.
+(Optional)
+(Alpha, PlayerTracking feature flag) Players provides the configuration for player tracking features.
|
-
-
-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
-
-
-
-
-Field |
-Description |
-
-
-
-url
+counters
-string
+
+map[string]agones.dev/agones/pkg/apis/agones/v1.CounterStatus
+
|
(Optional)
- url gives the location of the webhook, in standard URL form
-(scheme://host:port/path ). Exactly one of url or service
-must be specified.
-The host should not refer to a service running in the cluster; use
-the service field instead. The host might be resolved via external
-DNS in some apiservers (e.g., kube-apiserver cannot resolve
-in-cluster DNS as that would be a layering violation). host may
-also be an IP address.
-Please note that using localhost or 127.0.0.1 as a host is
-risky unless you take great care to run this webhook on all hosts
-which run an apiserver which might need to make calls to this
-webhook. Such installs are likely to be non-portable, i.e., not easy
-to turn up in a new cluster.
-The scheme must be “https”; the URL must begin with “https://”.
-A path is optional, and if present may be any string permissible in
-a URL. You may use the path to pass an arbitrary string to the
-webhook, for example, a cluster identifier.
-Attempting to use a user or basic auth e.g. “user:password@” is not
-allowed. Fragments (“#…”) and query parameters (“?…”) are not
-allowed, either.
+(Beta, CountsAndLists feature flag) Counters provides the configuration for tracking of int64 values against a GameServer.
+Keys must be declared at GameServer creation time.
|
-service
+lists
-
-Kubernetes admissionregistration/v1.ServiceReference
+
+map[string]agones.dev/agones/pkg/apis/agones/v1.ListStatus
|
(Optional)
- service is a reference to the service for this webhook. Either
-service or url must be specified.
-If the webhook is running within the cluster, then you should use service .
+(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.
|
-caBundle
+eviction
-[]byte
+
+Eviction
+
|
(Optional)
- caBundle is a PEM encoded CA bundle which will be used to validate the webhook’s server certificate.
-If unspecified, system trust roots on the apiserver are used.
+Eviction specifies the eviction tolerance of the GameServer. Defaults to “Never”.
+ |
+
+
|
-
-multicluster.agones.dev/v1
+Health
+
-
Package v1 is the v1 version of the API.
+(Appears on:
+GameServerSpec)
-Resource Types:
-
-GameServerAllocationPolicy
-
-
GameServerAllocationPolicy is the Schema for the gameserverallocationpolicies API
+Health configures health checking on the GameServer
@@ -1940,63 +1925,74 @@ GameServerAllocat
-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
|
-
-
-
+FailureThreshold how many failures in a row constitutes unhealthy
+
+
-priority
+initialDelaySeconds
int32
|
+ InitialDelaySeconds initial delay before checking health
|
+
+
+ListStatus
+
+
+(Appears on:
+GameServerAllocationStatus,
+GameServerSpec,
+GameServerStatus)
+
+
+ ListStatus stores the current list values and maximum capacity
+
+
+
+
+Field |
+Description |
+
+
+
-weight
+capacity
-int
+int64
|
@@ -2004,29 +2000,24 @@ GameServerAllocat
|
-connectionInfo
+values
-
-ClusterConnectionInfo
-
+[]string
|
|
-
- |
-
-ClusterConnectionInfo
+PlayerStatus
(Appears on:
-GameServerAllocationPolicySpec)
+GameServerStatus)
-
ClusterConnectionInfo defines the connection information for a cluster
+PlayerStatus stores the current player capacity values
@@ -2038,67 +2029,85 @@ ClusterConnectionInfo
-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.
|
-ConnectionInfoIterator
+PortPolicy
+(string
alias)
+
+(Appears on:
+GameServerPort)
+
+
+
PortPolicy is the port policy for the GameServer
+
+Priority
-
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.
@@ -2110,58 +2119,49 @@ ConnectionInfoIterato
-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”
|
-GameServerAllocationPolicySpec
+SdkServer
(Appears on:
-GameServerAllocationPolicy)
+GameServerSpec)
-
GameServerAllocationPolicySpec defines the desired state of GameServerAllocationPolicy
+SdkServer specifies parameters for the Agones SDK Server sidecar container
@@ -2173,55 +2173,64 @@ GameServerAll
-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
|
+SdkServerLogLevel
+(string
alias)
+
+(Appears on:
+SdkServer)
+
+
+
SdkServerLogLevel is the log level for SDK server (sidecar) logs
+
-agones.dev/v1
+allocation.agones.dev/v1
Package v1 is the v1 version of the API.
Resource Types:
-Fleet
+GameServerAllocation
-
Fleet is the data structure for a Fleet resource
+GameServerAllocation is the data structure for allocating against a set of
+GameServers, defined selectors
selectors
@@ -2237,7 +2246,7 @@ Fleet
string
-agones.dev/v1
+allocation.agones.dev/v1
|
@@ -2246,7 +2255,7 @@ Fleet
kind
string
-Fleet |
+GameServerAllocation |
@@ -2266,8 +2275,8 @@ Fleet
spec
-
-FleetSpec
+
+GameServerAllocationSpec
|
@@ -2277,41 +2286,86 @@ Fleet
-replicas
+multiClusterSetting
-int32
+
+MultiClusterSetting
+
|
- Replicas are the number of GameServers that should be in this set. Defaults to 0.
+MultiClusterPolicySelector if specified, multi-cluster policies are applied.
+Otherwise, allocation will happen locally.
|
-allocationOverflow
+required
-
-AllocationOverflow
+
+GameServerSelector
+
+
+ |
+
+ 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.
+ |
+
+
+
+preferred
+
+
+[]GameServerSelector
+
+
+ |
+
+ 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 required selector.
+If the first selector is not matched, the selection attempts the second selector, and so on.
+If any of the preferred selectors are matched, the required selector is not considered.
+This is useful for things like smoke testing of new game servers.
+ |
+
+
+
+priorities
+
+
+[]Priority
|
(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 GameServerSet
+[Stage: Beta]
+[FeatureFlag:CountsAndLists]
+Priorities configuration alters the order in which GameServers are searched for matches to the configured selectors .
+Priority of sorting is in descending importance. I.e. The position 0 priority entry is checked first.
+For Packed strategy sorting, this priority list will be the tie-breaker within the least utilised infrastructure, to ensure optimal
+infrastructure usage while also allowing some custom prioritisation of GameServers .
+For Distributed strategy sorting, the entire selection of GameServers will be sorted by this priority list to provide the
+order that GameServers will be allocated by.
|
-strategy
+selectors
-
-Kubernetes apps/v1.DeploymentStrategy
+
+[]GameServerSelector
|
- Deployment strategy
+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.
|
@@ -2327,36 +2381,48 @@ Fleet
-priorities
+metadata
-
-[]Priority
+
+MetaPatch
+
+
+ |
+
+ 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
+ |
+
+
+
+counters
+
+
+map[string]agones.dev/agones/pkg/apis/allocation/v1.CounterAction
|
(Optional)
- [Stage: Alpha]
+ [Stage: Beta]
[FeatureFlag:CountsAndLists]
-Priorities configuration alters scale down logic in Fleets based on the configured available capacity order under that key.
-Priority of sorting is in descending importance. I.e. The position 0 priority entry is checked first.
-For Packed strategy scale down, this priority list will be the tie-breaker within the node, to ensure optimal
-infrastructure usage while also allowing some custom prioritisation of GameServers .
-For Distributed strategy scale down, the entire Fleet will be sorted by this priority list to provide the
-order of GameServers to delete on scale down.
+Counter actions to perform during allocation.
|
-template
+lists
-
-GameServerTemplateSpec
+
+map[string]agones.dev/agones/pkg/apis/allocation/v1.ListAction
|
- Template the GameServer template to apply for this Fleet
+(Optional)
+[Stage: Beta]
+[FeatureFlag:CountsAndLists]
+List actions to perform during allocation.
|
@@ -2366,8 +2432,8 @@ Fleet
status
-
-FleetStatus
+
+GameServerAllocationStatus
|
@@ -2376,14 +2442,69 @@ Fleet
|
-GameServer
+CounterAction
+
+
+(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.
+ |
+
+
+
+CounterSelector
-
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.
+(Appears on:
+GameServerSelector)
+
+
+
CounterSelector is the filter options for a GameServer based on the count and/or available capacity.
@@ -2395,204 +2516,231 @@ GameServer
-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
|
-
-
-
+(Optional)
+MaxCount is the maximum current value. Defaults to 0, which translates as max(in64).
+
+
-container
+minAvailable
-string
+int64
|
- Container specifies which Pod container is the game server. Only required if there is more than one
-container defined
+(Optional)
+MinAvailable specifies the minimum capacity (current capacity - current count) available on a GameServer. Defaults to 0.
|
-ports
+maxAvailable
-
-[]GameServerPort
-
+int64
|
- Ports are the array of ports that can be exposed via the game server
+(Optional)
+MaxAvailable specifies the maximum capacity (current capacity - current count) available on a GameServer. Defaults to 0, which translates to max(int64).
|
+
+
+GameServerAllocationSpec
+
+
+(Appears on:
+GameServerAllocation)
+
+
+ GameServerAllocationSpec is the spec for a GameServerAllocation
+
+
+
+
+Field |
+Description |
+
+
+
-health
+multiClusterSetting
-
-Health
+
+MultiClusterSetting
|
- Health configures health checking
+MultiClusterPolicySelector if specified, multi-cluster policies are applied.
+Otherwise, allocation will happen locally.
|
-scheduling
+required
-agones.dev/agones/pkg/apis.SchedulingStrategy
+
+GameServerSelector
+
|
- Scheduling strategy. Defaults to “Packed”
+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.
|
-sdkServer
+preferred
-
-SdkServer
+
+[]GameServerSelector
|
- SdkServer specifies parameters for the Agones SDK Server sidecar container
+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 required selector.
+If the first selector is not matched, the selection attempts the second selector, and so on.
+If any of the preferred selectors are matched, the required selector is not considered.
+This is useful for things like smoke testing of new game servers.
|
-template
+priorities
-
-Kubernetes core/v1.PodTemplateSpec
+
+[]Priority
|
- Template describes the Pod that will be created for the GameServer
+(Optional)
+[Stage: Beta]
+[FeatureFlag:CountsAndLists]
+Priorities configuration alters the order in which GameServers are searched for matches to the configured selectors .
+Priority of sorting is in descending importance. I.e. The position 0 priority entry is checked first.
+For Packed strategy sorting, this priority list will be the tie-breaker within the least utilised infrastructure, to ensure optimal
+infrastructure usage while also allowing some custom prioritisation of GameServers .
+For Distributed strategy sorting, the entire selection of GameServers will be sorted by this priority list to provide the
+order that GameServers will be allocated by.
|
-players
+selectors
-
-PlayersSpec
+
+[]GameServerSelector
|
-(Optional)
- (Alpha, PlayerTracking feature flag) Players provides the configuration for player tracking features.
+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.
|
-counters
+scheduling
-
-map[string]agones.dev/agones/pkg/apis/agones/v1.CounterStatus
-
+agones.dev/agones/pkg/apis.SchedulingStrategy
|
-(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.
+Scheduling strategy. Defaults to “Packed”.
|
-lists
+metadata
-
-map[string]agones.dev/agones/pkg/apis/agones/v1.ListStatus
+
+MetaPatch
|
-(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.
+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
|
-eviction
+counters
-
-Eviction
+
+map[string]agones.dev/agones/pkg/apis/allocation/v1.CounterAction
|
(Optional)
- Eviction specifies the eviction tolerance of the GameServer. Defaults to “Never”.
- |
-
-
+[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.
|
-GameServerSet
+GameServerAllocationState
+(string
alias)
+
+(Appears on:
+GameServerAllocationStatus)
+
+
+
GameServerAllocationState is the Allocation state
+
+GameServerAllocationStatus
-
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
@@ -2604,129 +2752,153 @@ GameServerSet
-apiVersion
-string |
+state
+
+
+GameServerAllocationState
+
+
+
-
-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
|
-
-
-
+
+
-replicas
+nodeName
-int32
+string
|
- Replicas are the number of GameServers that should be in this set
|
-allocationOverflow
+source
-
-AllocationOverflow
-
+string
|
-(Optional)
- Labels and Annotations to apply to GameServers when the number of Allocated GameServers drops below
-the desired replicas on the underlying GameServerSet
+If the allocation is from a remote cluster, Source is the endpoint of the remote agones-allocator.
+Otherwise, Source is “local”
|
-scheduling
+metadata
-agones.dev/agones/pkg/apis.SchedulingStrategy
+
+GameServerMetadata
+
|
- Scheduling strategy. Defaults to “Packed”.
|
-priorities
+counters
-
-[]Priority
+
+map[string]agones.dev/agones/pkg/apis/agones/v1.CounterStatus
|
-(Optional)
- [Stage: Alpha]
-[FeatureFlag:CountsAndLists]
-Priorities configuration alters scale down logic in Fleets based on the configured available capacity order under that key.
-Priority of sorting is in descending importance. I.e. The position 0 priority entry is checked first.
-For Packed strategy scale down, this priority list will be the tie-breaker within the node, to ensure optimal
-infrastructure usage while also allowing some custom prioritisation of GameServers .
-For Distributed strategy scale down, the entire Fleet will be sorted by this priority list to provide the
-order of GameServers to delete on scale down.
|
-template
+lists
-
-GameServerTemplateSpec
+
+map[string]agones.dev/agones/pkg/apis/agones/v1.ListStatus
|
- Template the GameServer template to apply for this GameServerSet
|
+
+GameServerMetadata
+
+
+(Appears on:
+GameServerAllocationStatus)
+
+
+ GameServerMetadata is the metadata from the allocated game server at allocation time
+
+
+
+
+Field |
+Description |
+
+
+
+
+
+labels
+
+map[string]string
+
+ |
+
|
-status
+annotations
-
-GameServerSetStatus
-
+map[string]string
|
@@ -2734,15 +2906,15 @@ GameServerSet
|
-AggregatedCounterStatus
+GameServerSelector
(Appears on:
-FleetStatus,
-GameServerSetStatus)
+GameServerAllocationSpec)
- AggregatedCounterStatus stores total and allocated Counter tracking values
+GameServerSelector contains all the filter options for selecting
+a GameServer for allocation.
@@ -2754,55 +2926,98 @@ AggregatedCounterStatus
-allocatedCount
+LabelSelector
-int64
+
+Kubernetes meta/v1.LabelSelector
+
|
+
+(Members of LabelSelector are embedded into this type.)
+
+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.
|
-AggregatedListStatus
+ListAction
(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.
@@ -2814,32 +3029,14 @@ AggregatedListStatus
-allocatedCount
-
-int64
-
- |
-
- |
-
-
-
-allocatedCapacity
-
-int64
-
- |
-
- |
-
-
-
-count
+addValues
-int64
+[]string
|
+(Optional)
+ AddValues appends values to a List’s Values array. Any duplicate values will be ignored.
|
@@ -2850,19 +3047,21 @@ AggregatedListStatus
+(Optional)
+ Capacity updates the maximum capacity of the Counter to this number. Min 0, Max 1000.
|
-AggregatedPlayerStatus
+ListSelector
(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.
@@ -2874,37 +3073,50 @@ AggregatedPlayerStatus
-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).
|
-AllocationOverflow
+MetaPatch
(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
@@ -2922,8 +3134,6 @@ AllocationOverflow
-(Optional)
- Labels to be applied to the GameServer
|
@@ -2934,22 +3144,18 @@ AllocationOverflow
-(Optional)
- Annotations to be applied to the GameServer
|
-CounterStatus
+MultiClusterSetting
(Appears on:
-GameServerAllocationStatus,
-GameServerSpec,
-GameServerStatus)
+GameServerAllocationSpec)
- CounterStatus stores the current counter values and maximum capacity
+MultiClusterSetting specifies settings for multi-cluster allocation.
@@ -2961,9 +3167,9 @@ CounterStatus
-count
+enabled
-int64
+bool
|
@@ -2971,9 +3177,11 @@ CounterStatus
|
-capacity
+policySelector
-int64
+
+Kubernetes meta/v1.LabelSelector
+
|
@@ -2981,15 +3189,14 @@ CounterStatus
|
-Eviction
+PlayerSelector
(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
@@ -3001,39 +3208,39 @@ Eviction
-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
|
-EvictionSafe
-(string alias)
-
-(Appears on:
-Eviction)
-
+
+autoscaling.agones.dev/v1
- EvictionSafe specified whether the game server supports termination via SIGTERM
+Package v1 is the v1 version of the API.
-FleetSpec
+Resource Types:
+
+FleetAutoscaler
-(Appears on:
-Fleet)
-
-
- FleetSpec is the spec for a Fleet
+FleetAutoscaler is the data structure for a FleetAutoscaler resource
@@ -3045,99 +3252,110 @@ FleetSpec
-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 GameServerSet
+Refer to the Kubernetes API documentation for the fields of the
+metadata field.
|
-strategy
+spec
-
-Kubernetes apps/v1.DeploymentStrategy
+
+FleetAutoscalerSpec
|
- Deployment strategy
+
+
+
+
+
+fleetName
+
+string
+
+ |
+
|
-scheduling
+policy
-agones.dev/agones/pkg/apis.SchedulingStrategy
+
+FleetAutoscalerPolicy
+
|
- Scheduling strategy. Defaults to “Packed”.
+Autoscaling policy
|
-priorities
+sync
-
-[]Priority
+
+FleetAutoscalerSync
|
(Optional)
- [Stage: Alpha]
-[FeatureFlag:CountsAndLists]
-Priorities configuration alters scale down logic in Fleets based on the configured available capacity order under that key.
-Priority of sorting is in descending importance. I.e. The position 0 priority entry is checked first.
-For Packed strategy scale down, this priority list will be the tie-breaker within the node, to ensure optimal
-infrastructure usage while also allowing some custom prioritisation of GameServers .
-For Distributed strategy scale down, the entire Fleet will be sorted by this priority list to provide the
-order of GameServers to delete on scale down.
+Sync defines when FleetAutoscalers runs autoscaling
+ |
+
+
|
-template
+status
-
-GameServerTemplateSpec
+
+FleetAutoscalerStatus
|
- Template the GameServer template to apply for this Fleet
|
-FleetStatus
+ActivePeriod
(Appears on:
-Fleet,
-FleetAutoscaleRequest)
+Schedule)
- FleetStatus is the status of a Fleet
+ActivePeriod defines the time period that the policy is applied.
@@ -3149,106 +3367,94 @@ FleetStatus
-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”.
|
+
+
+Between
+
+
+(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.
|
-GameServerPort
+BufferPolicy
(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.
@@ -3260,102 +3466,120 @@ GameServerPort
-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 Static portPolicy is specified, HostPort is required, to specify the port that game clients will
-connect to
+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
+
+
+ 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.
|
-GameServerSetSpec
+ChainPolicy
+([]agones.dev/agones/pkg/apis/autoscaling/v1.ChainEntry alias)
+
+(Appears on:
+FleetAutoscalerPolicy)
+
+
+ ChainPolicy controls the desired behavior of the Chain autoscaler policy.
+
+CounterPolicy
(Appears on:
-GameServerSet)
+FleetAutoscalerPolicy)
- GameServerSetSpec the specification for GameServerSet
+CounterPolicy controls the desired behavior of the Counter autoscaler policy.
@@ -3367,85 +3591,94 @@ GameServerSetSpec
-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 GameServerSet
+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]
-Priorities configuration alters scale down logic in Fleets based on the configured available capacity order under that key.
-Priority of sorting is in descending importance. I.e. The position 0 priority entry is checked first.
-For Packed strategy scale down, this priority list will be the tie-breaker within the node, to ensure optimal
-infrastructure usage while also allowing some custom prioritisation of GameServers .
-For Distributed strategy scale down, the entire Fleet will be sorted by this priority list to provide the
-order of GameServers to delete on scale down.
+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.
|
+
+
+FixedIntervalSync
+
+
+(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
|
-GameServerSetStatus
+FleetAutoscaleRequest
(Appears on:
-GameServerSet)
+FleetAutoscaleReview)
- GameServerSetStatus is the status of a GameServerSet
+FleetAutoscaleRequest defines the request to webhook autoscaler endpoint
@@ -3457,116 +3690,113 @@ GameServerSetStatus
-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
|
+
+
+FleetAutoscaleResponse
+
+
+(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
|
-GameServerSpec
+FleetAutoscaleReview
-(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.
@@ -3578,157 +3808,157 @@ GameServerSpec
-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
|
+
+
+FleetAutoscalerPolicy
+
+
+(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.
|
-GameServerState
+FleetAutoscalerPolicyType
(string alias)
(Appears on:
-GameServerSelector,
-GameServerStatus)
+FleetAutoscalerPolicy)
- GameServerState is the state for the GameServer
+FleetAutoscalerPolicyType is the policy for autoscaling
+for a given Fleet
-GameServerStatus
+FleetAutoscalerSpec
(Appears on:
-GameServer)
+FleetAutoscaler)
- GameServerStatus is the status for a GameServer resource
+FleetAutoscalerSpec is the spec for a Fleet Scaler
+FleetAutoscalerStatus
+
+
+(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.
|
-GameServerStatusPort
+FleetAutoscalerSync
(Appears on:
-GameServerAllocationStatus,
-GameServerStatus)
+FleetAutoscalerSpec)
- GameServerStatusPort shows the port that was allocated to a
-GameServer.
+FleetAutoscalerSync describes when to sync a fleet
@@ -3888,35 +4106,50 @@ GameServerStatusPort
-name
+type
-string
+
+FleetAutoscalerSyncType
+
|
+ Type of autoscaling sync.
|
-port
+fixedInterval
-int32
+
+FixedIntervalSync
+
|
+(Optional)
+ FixedInterval config params. Present only if FleetAutoscalerSyncType = FixedInterval.
|
-GameServerTemplateSpec
+FleetAutoscalerSyncType
+(string alias)
+
+(Appears on:
+FleetAutoscalerSync)
+
+
+ FleetAutoscalerSyncType is the sync strategy for a given Fleet
+
+ListPolicy
(Appears on:
-FleetSpec,
-GameServerSetSpec)
+FleetAutoscalerPolicy)
- GameServerTemplateSpec is a template for GameServers
+ListPolicy controls the desired behavior of the List autoscaler policy.
@@ -3928,177 +4161,195 @@ GameServerTemplateSpec
-metadata
-
-
-Kubernetes meta/v1.ObjectMeta
-
-
- |
-
-Refer to the Kubernetes API documentation for the fields of the
-metadata field.
- |
-
-
-
-spec
-
-
-GameServerSpec
-
-
- |
-
-
-
-
-
-
-container
+key
string
|
- Container specifies which Pod container is the game server. Only required if there is more than one
-container defined
+Key is the name of the List. Required field.
|
-ports
+maxCapacity
-
-[]GameServerPort
-
+int64
|
- Ports are the array of ports that can be exposed via the game server
+MaxCapacity is the maximum aggregate List total capacity across the fleet.
+MaxCapacity must be bigger than both MinCapacity and BufferSize. Required field.
|
-health
+minCapacity
-
-Health
-
+int64
|
- Health configures health checking
+MinCapacity is the minimum aggregate List total capacity across the fleet.
+If zero, it is ignored.
+If non zero, it must be smaller than MaxCapacity and bigger than BufferSize.
|
-scheduling
+bufferSize
-agones.dev/agones/pkg/apis.SchedulingStrategy
+k8s.io/apimachinery/pkg/util/intstr.IntOrString
|
- Scheduling strategy. Defaults to “Packed”
+BufferSize is the size of a buffer based on the List capacity that is available over the
+current aggregate List length in the Fleet (available capacity). It can be specified either
+as an absolute value (i.e. 5) or percentage format (i.e. 5%).
+Must be bigger than 0. Required field.
|
+
+
+Schedule
+
+
+(Appears on:
+ChainEntry)
+
+
+ Schedule defines when the policy should be applied.
+
+
+
+
+Field |
+Description |
+
+
+
-sdkServer
+between
-
-SdkServer
+
+Between
|
- SdkServer specifies parameters for the Agones SDK Server sidecar container
+Between defines the time period that the policy is eligible to be applied.
|
-template
+activePeriod
-
-Kubernetes core/v1.PodTemplateSpec
+
+ActivePeriod
|
- Template describes the Pod that will be created for the GameServer
+ActivePeriod defines the time period that the policy is 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
+
+
+
-
-players
-
-
-PlayersSpec
-
-
- |
-
-(Optional)
- (Alpha, PlayerTracking feature flag) Players provides the configuration for player tracking features.
- |
+Field |
+Description |
+
+
-counters
+url
-
-map[string]agones.dev/agones/pkg/apis/agones/v1.CounterStatus
-
+string
|
(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.
+url gives the location of the webhook, in standard URL form
+(scheme://host:port/path ). Exactly one of url or service
+must be specified.
+The host should not refer to a service running in the cluster; use
+the service field instead. The host might be resolved via external
+DNS in some apiservers (e.g., kube-apiserver cannot resolve
+in-cluster DNS as that would be a layering violation). host may
+also be an IP address.
+Please note that using localhost or 127.0.0.1 as a host is
+risky unless you take great care to run this webhook on all hosts
+which run an apiserver which might need to make calls to this
+webhook. Such installs are likely to be non-portable, i.e., not easy
+to turn up in a new cluster.
+The scheme must be “https”; the URL must begin with “https://”.
+A path is optional, and if present may be any string permissible in
+a URL. You may use the path to pass an arbitrary string to the
+webhook, for example, a cluster identifier.
+Attempting to use a user or basic auth e.g. “user:password@” is not
+allowed. Fragments (“#…”) and query parameters (“?…”) are not
+allowed, either.
|
-lists
+service
-
-map[string]agones.dev/agones/pkg/apis/agones/v1.ListStatus
+
+Kubernetes admissionregistration/v1.ServiceReference
|
(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.
+service is a reference to the service for this webhook. Either
+service or url must be specified.
+If the webhook is running within the cluster, then you should use service .
|
-eviction
+caBundle
-
-Eviction
-
+[]byte
|
(Optional)
- Eviction specifies the eviction tolerance of the GameServer. Defaults to “Never”.
- |
-
-
+caBundle is a PEM encoded CA bundle which will be used to validate the webhook’s server certificate.
+If unspecified, system trust roots on the apiserver are used.
|
-Health
-
+
+multicluster.agones.dev/v1
-(Appears on:
-GameServerSpec)
+ Package v1 is the v1 version of the API.
+Resource Types:
+
+GameServerAllocationPolicy
+
- Health configures health checking on the GameServer
+GameServerAllocationPolicy is the Schema for the gameserverallocationpolicies API
@@ -4110,74 +4361,63 @@ Health
-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
|
-
-
-ListStatus
-
-
-(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
+
|
|
+
+
+
-PlayerStatus
+ClusterConnectionInfo
(Appears on:
-GameServerStatus)
+GameServerAllocationPolicySpec)
- PlayerStatus stores the current player capacity values
+ClusterConnectionInfo defines the connection information for a cluster
@@ -4214,85 +4459,67 @@ PlayerStatus
-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.
|
-PortPolicy
-(string alias)
-
-(Appears on:
-GameServerPort)
-
-
- PortPolicy is the port policy for the GameServer
-
-Priority
+ConnectionInfoIterator
-(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
@@ -4304,49 +4531,58 @@ Priority
-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
|
-SdkServer
+GameServerAllocationPolicySpec
(Appears on:
-GameServerSpec)
+GameServerAllocationPolicy)
- SdkServer specifies parameters for the Agones SDK Server sidecar container
+GameServerAllocationPolicySpec defines the desired state of GameServerAllocationPolicy
@@ -4358,56 +4594,44 @@ SdkServer
-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
|
-SdkServerLogLevel
-(string alias)
-
-(Appears on:
-SdkServer)
-
-
- SdkServerLogLevel is the log level for SDK server (sidecar) logs
-
Generated with gen-crd-api-reference-docs .
{{% /feature %}}
-{{% feature publishVersion="1.41.0" %}}
+{{% feature publishVersion="1.43.0" %}}
Packages:
-
@@ -7752,6 +7976,113 @@
FleetAutoscaler
|
+ActivePeriod
+
+
+(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”.
+ |
+
+
+
+Between
+
+
+(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.
+ |
+
+
+
BufferPolicy
@@ -7816,6 +8147,57 @@
BufferPolicy
+ChainEntry
+
+
+
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 FleetAutoscalerPolicy are embedded into this type.)
+
+Policy is the name of the policy to be applied. Required field.
+ |
+
+
+
+ChainPolicy
+([]agones.dev/agones/pkg/apis/autoscaling/v1.ChainEntry
alias)
+
+(Appears on:
+FleetAutoscalerPolicy)
+
+
+
ChainPolicy controls the desired behavior of the Chain autoscaler policy.
+
CounterPolicy
@@ -8080,7 +8462,9 @@
FleetAutoscalerPolicy
(Appears on:
-FleetAutoscalerSpec)
+ChainEntry,
+FleetAutoscalerSpec,
+SchedulePolicy)
FleetAutoscalerPolicy describes how to scale a fleet
@@ -8166,6 +8550,38 @@ FleetAutoscalerPolicy
List policy config params. Present only if FleetAutoscalerPolicyType = List.
+
+
+schedule
+
+
+SchedulePolicy
+
+
+ |
+
+(Optional)
+ [Stage:Dev]
+[FeatureFlag:ScheduledAutoscaler]
+Schedule policy config params. Present only if FleetAutoscalerPolicyType = Schedule.
+ |
+
+
+
+chain
+
+
+ChainPolicy
+
+
+ |
+
+(Optional)
+ [Stage:Dev]
+[FeatureFlag:ScheduledAutoscaler]
+Chain policy config params. Present only if FleetAutoscalerPolicyType = Chain.
+ |
+
FleetAutoscalerPolicyType
@@ -8438,6 +8854,64 @@ ListPolicy
+SchedulePolicy
+
+
+(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.
+ |
+
+
+
WebhookPolicy
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
+
+where "duration" is a string accepted by time.ParseDuration
+(http://golang.org/pkg/time/#ParseDuration).
+
+For example, "@every 1h30m10s" would indicate a schedule that activates after
+1 hour, 30 minutes, 10 seconds, and then every interval after that.
+
+Note: The interval does not take the job runtime into account. For example,
+if a job takes 3 minutes to run, and it is scheduled to run every 5 minutes,
+it will have only 2 minutes of idle time between each run.
+
+Time zones
+
+By default, all interpretation and scheduling is done in the machine's local
+time zone (time.Local). You can specify a different time zone on construction:
+
+ cron.New(
+ cron.WithLocation(time.UTC))
+
+Individual cron schedules may also override the time zone they are to be
+interpreted in by providing an additional space-separated field at the beginning
+of the cron spec, of the form "CRON_TZ=Asia/Tokyo".
+
+For example:
+
+ # Runs at 6am in time.Local
+ cron.New().AddFunc("0 6 * * ?", ...)
+
+ # Runs at 6am in America/New_York
+ nyc, _ := time.LoadLocation("America/New_York")
+ c := cron.New(cron.WithLocation(nyc))
+ c.AddFunc("0 6 * * ?", ...)
+
+ # Runs at 6am in Asia/Tokyo
+ cron.New().AddFunc("CRON_TZ=Asia/Tokyo 0 6 * * ?", ...)
+
+ # Runs at 6am in Asia/Tokyo
+ c := cron.New(cron.WithLocation(nyc))
+ c.SetLocation("America/New_York")
+ c.AddFunc("CRON_TZ=Asia/Tokyo 0 6 * * ?", ...)
+
+The prefix "TZ=(TIME ZONE)" is also supported for legacy compatibility.
+
+Be aware that jobs scheduled during daylight-savings leap-ahead transitions will
+not be run!
+
+Job Wrappers
+
+A Cron runner may be configured with a chain of job wrappers to add
+cross-cutting functionality to all submitted jobs. For example, they may be used
+to achieve the following effects:
+
+ - Recover any panics from jobs (activated by default)
+ - 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
+
+Install wrappers for all jobs added to a cron using the `cron.WithChain` option:
+
+ cron.New(cron.WithChain(
+ cron.SkipIfStillRunning(logger),
+ ))
+
+Install wrappers for individual jobs by explicitly wrapping them:
+
+ job = cron.NewChain(
+ cron.SkipIfStillRunning(logger),
+ ).Then(job)
+
+Thread safety
+
+Since the Cron service runs concurrently with the calling code, some amount of
+care must be taken to ensure proper synchronization.
+
+All cron methods are designed to be correctly synchronized as long as the caller
+ensures that invocations have a clear happens-before ordering between them.
+
+Logging
+
+Cron defines a Logger interface that is a subset of the one defined in
+github.com/go-logr/logr. It has two logging levels (Info and Error), and
+parameters are key/value pairs. This makes it possible for cron logging to plug
+into structured logging systems. An adapter, [Verbose]PrintfLogger, is provided
+to wrap the standard library *log.Logger.
+
+For additional insight into Cron operations, verbose logging may be activated
+which will record job runs, scheduling decisions, and added or removed jobs.
+Activate it with a one-off logger as follows:
+
+ cron.New(
+ cron.WithLogger(
+ cron.VerbosePrintfLogger(log.New(os.Stdout, "cron: ", log.LstdFlags))))
+
+
+Implementation
+
+Cron entries are stored in an array, sorted by their next activation time. Cron
+sleeps until the next job is due to be run.
+
+Upon waking:
+ - it runs each entry that is active on that second
+ - it calculates the next run times for the jobs that were run
+ - it re-sorts the array of entries by next activation time.
+ - it goes to sleep until the soonest job.
+*/
+package cron
diff --git a/vendor/github.com/robfig/cron/v3/logger.go b/vendor/github.com/robfig/cron/v3/logger.go
new file mode 100644
index 0000000000..b4efcc0535
--- /dev/null
+++ b/vendor/github.com/robfig/cron/v3/logger.go
@@ -0,0 +1,86 @@
+package cron
+
+import (
+ "io/ioutil"
+ "log"
+ "os"
+ "strings"
+ "time"
+)
+
+// DefaultLogger is used by Cron if none is specified.
+var DefaultLogger Logger = PrintfLogger(log.New(os.Stdout, "cron: ", log.LstdFlags))
+
+// DiscardLogger can be used by callers to discard all log messages.
+var DiscardLogger Logger = PrintfLogger(log.New(ioutil.Discard, "", 0))
+
+// Logger is the interface used in this package for logging, so that any backend
+// can be plugged in. It is a subset of the github.com/go-logr/logr interface.
+type Logger interface {
+ // Info logs routine messages about cron's operation.
+ Info(msg string, keysAndValues ...interface{})
+ // Error logs an error condition.
+ Error(err error, msg string, keysAndValues ...interface{})
+}
+
+// PrintfLogger wraps a Printf-based logger (such as the standard library "log")
+// into an implementation of the Logger interface which logs errors only.
+func PrintfLogger(l interface{ Printf(string, ...interface{}) }) Logger {
+ return printfLogger{l, false}
+}
+
+// VerbosePrintfLogger wraps a Printf-based logger (such as the standard library
+// "log") into an implementation of the Logger interface which logs everything.
+func VerbosePrintfLogger(l interface{ Printf(string, ...interface{}) }) Logger {
+ return printfLogger{l, true}
+}
+
+type printfLogger struct {
+ logger interface{ Printf(string, ...interface{}) }
+ logInfo bool
+}
+
+func (pl printfLogger) Info(msg string, keysAndValues ...interface{}) {
+ if pl.logInfo {
+ keysAndValues = formatTimes(keysAndValues)
+ pl.logger.Printf(
+ formatString(len(keysAndValues)),
+ append([]interface{}{msg}, keysAndValues...)...)
+ }
+}
+
+func (pl printfLogger) Error(err error, msg string, keysAndValues ...interface{}) {
+ keysAndValues = formatTimes(keysAndValues)
+ pl.logger.Printf(
+ formatString(len(keysAndValues)+2),
+ append([]interface{}{msg, "error", err}, keysAndValues...)...)
+}
+
+// formatString returns a logfmt-like format string for the number of
+// key/values.
+func formatString(numKeysAndValues int) string {
+ var sb strings.Builder
+ sb.WriteString("%s")
+ if numKeysAndValues > 0 {
+ sb.WriteString(", ")
+ }
+ for i := 0; i < numKeysAndValues/2; i++ {
+ if i > 0 {
+ sb.WriteString(", ")
+ }
+ sb.WriteString("%v=%v")
+ }
+ return sb.String()
+}
+
+// formatTimes formats any time.Time values as RFC3339.
+func formatTimes(keysAndValues []interface{}) []interface{} {
+ var formattedArgs []interface{}
+ for _, arg := range keysAndValues {
+ if t, ok := arg.(time.Time); ok {
+ arg = t.Format(time.RFC3339)
+ }
+ formattedArgs = append(formattedArgs, arg)
+ }
+ return formattedArgs
+}
diff --git a/vendor/github.com/robfig/cron/v3/option.go b/vendor/github.com/robfig/cron/v3/option.go
new file mode 100644
index 0000000000..09e4278e77
--- /dev/null
+++ b/vendor/github.com/robfig/cron/v3/option.go
@@ -0,0 +1,45 @@
+package cron
+
+import (
+ "time"
+)
+
+// Option represents a modification to the default behavior of a Cron.
+type Option func(*Cron)
+
+// WithLocation overrides the timezone of the cron instance.
+func WithLocation(loc *time.Location) Option {
+ return func(c *Cron) {
+ c.location = loc
+ }
+}
+
+// WithSeconds overrides the parser used for interpreting job schedules to
+// include a seconds field as the first one.
+func WithSeconds() Option {
+ return WithParser(NewParser(
+ Second | Minute | Hour | Dom | Month | Dow | Descriptor,
+ ))
+}
+
+// WithParser overrides the parser used for interpreting job schedules.
+func WithParser(p ScheduleParser) Option {
+ return func(c *Cron) {
+ c.parser = p
+ }
+}
+
+// WithChain specifies Job wrappers to apply to all jobs added to this cron.
+// Refer to the Chain* functions in this package for provided wrappers.
+func WithChain(wrappers ...JobWrapper) Option {
+ return func(c *Cron) {
+ c.chain = NewChain(wrappers...)
+ }
+}
+
+// WithLogger uses the provided logger.
+func WithLogger(logger Logger) Option {
+ return func(c *Cron) {
+ c.logger = logger
+ }
+}
diff --git a/vendor/github.com/robfig/cron/v3/parser.go b/vendor/github.com/robfig/cron/v3/parser.go
new file mode 100644
index 0000000000..3cf8879f7e
--- /dev/null
+++ b/vendor/github.com/robfig/cron/v3/parser.go
@@ -0,0 +1,434 @@
+package cron
+
+import (
+ "fmt"
+ "math"
+ "strconv"
+ "strings"
+ "time"
+)
+
+// Configuration options for creating a parser. Most options specify which
+// fields should be included, while others enable features. If a field is not
+// included the parser will assume a default value. These options do not change
+// the order fields are parse in.
+type ParseOption int
+
+const (
+ Second ParseOption = 1 << iota // Seconds field, default 0
+ SecondOptional // Optional seconds field, default 0
+ Minute // Minutes field, default 0
+ Hour // Hours field, default 0
+ Dom // Day of month field, default *
+ Month // Month field, default *
+ Dow // Day of week field, default *
+ DowOptional // Optional day of week field, default *
+ Descriptor // Allow descriptors such as @monthly, @weekly, etc.
+)
+
+var places = []ParseOption{
+ Second,
+ Minute,
+ Hour,
+ Dom,
+ Month,
+ Dow,
+}
+
+var defaults = []string{
+ "0",
+ "0",
+ "0",
+ "*",
+ "*",
+ "*",
+}
+
+// A custom Parser that can be configured.
+type Parser struct {
+ options ParseOption
+}
+
+// NewParser creates a Parser with custom options.
+//
+// It panics if more than one Optional is given, since it would be impossible to
+// correctly infer which optional is provided or missing in general.
+//
+// Examples
+//
+// // Standard parser without descriptors
+// specParser := NewParser(Minute | Hour | Dom | Month | Dow)
+// sched, err := specParser.Parse("0 0 15 */3 *")
+//
+// // Same as above, just excludes time fields
+// subsParser := NewParser(Dom | Month | Dow)
+// sched, err := specParser.Parse("15 */3 *")
+//
+// // Same as above, just makes Dow optional
+// subsParser := NewParser(Dom | Month | DowOptional)
+// sched, err := specParser.Parse("15 */3")
+//
+func NewParser(options ParseOption) Parser {
+ optionals := 0
+ if options&DowOptional > 0 {
+ optionals++
+ }
+ if options&SecondOptional > 0 {
+ optionals++
+ }
+ if optionals > 1 {
+ panic("multiple optionals may not be configured")
+ }
+ return Parser{options}
+}
+
+// Parse returns a new crontab schedule representing the given spec.
+// It returns a descriptive error if the spec is not valid.
+// It accepts crontab specs and features configured by NewParser.
+func (p Parser) Parse(spec string) (Schedule, error) {
+ if len(spec) == 0 {
+ return nil, fmt.Errorf("empty spec string")
+ }
+
+ // Extract timezone if present
+ var loc = time.Local
+ if strings.HasPrefix(spec, "TZ=") || strings.HasPrefix(spec, "CRON_TZ=") {
+ var err error
+ i := strings.Index(spec, " ")
+ eq := strings.Index(spec, "=")
+ if loc, err = time.LoadLocation(spec[eq+1 : i]); err != nil {
+ return nil, fmt.Errorf("provided bad location %s: %v", spec[eq+1:i], err)
+ }
+ spec = strings.TrimSpace(spec[i:])
+ }
+
+ // Handle named schedules (descriptors), if configured
+ if strings.HasPrefix(spec, "@") {
+ if p.options&Descriptor == 0 {
+ return nil, fmt.Errorf("parser does not accept descriptors: %v", spec)
+ }
+ return parseDescriptor(spec, loc)
+ }
+
+ // Split on whitespace.
+ fields := strings.Fields(spec)
+
+ // Validate & fill in any omitted or optional fields
+ var err error
+ fields, err = normalizeFields(fields, p.options)
+ if err != nil {
+ return nil, err
+ }
+
+ field := func(field string, r bounds) uint64 {
+ if err != nil {
+ return 0
+ }
+ var bits uint64
+ bits, err = getField(field, r)
+ return bits
+ }
+
+ var (
+ second = field(fields[0], seconds)
+ minute = field(fields[1], minutes)
+ hour = field(fields[2], hours)
+ dayofmonth = field(fields[3], dom)
+ month = field(fields[4], months)
+ dayofweek = field(fields[5], dow)
+ )
+ if err != nil {
+ return nil, err
+ }
+
+ return &SpecSchedule{
+ Second: second,
+ Minute: minute,
+ Hour: hour,
+ Dom: dayofmonth,
+ Month: month,
+ Dow: dayofweek,
+ Location: loc,
+ }, nil
+}
+
+// normalizeFields takes a subset set of the time fields and returns the full set
+// with defaults (zeroes) populated for unset fields.
+//
+// As part of performing this function, it also validates that the provided
+// fields are compatible with the configured options.
+func normalizeFields(fields []string, options ParseOption) ([]string, error) {
+ // Validate optionals & add their field to options
+ optionals := 0
+ if options&SecondOptional > 0 {
+ options |= Second
+ optionals++
+ }
+ if options&DowOptional > 0 {
+ options |= Dow
+ optionals++
+ }
+ if optionals > 1 {
+ return nil, fmt.Errorf("multiple optionals may not be configured")
+ }
+
+ // Figure out how many fields we need
+ max := 0
+ for _, place := range places {
+ if options&place > 0 {
+ max++
+ }
+ }
+ min := max - optionals
+
+ // Validate number of fields
+ if count := len(fields); count < min || count > max {
+ if min == max {
+ return nil, fmt.Errorf("expected exactly %d fields, found %d: %s", min, count, fields)
+ }
+ return nil, fmt.Errorf("expected %d to %d fields, found %d: %s", min, max, count, fields)
+ }
+
+ // Populate the optional field if not provided
+ if min < max && len(fields) == min {
+ switch {
+ case options&DowOptional > 0:
+ fields = append(fields, defaults[5]) // TODO: improve access to default
+ case options&SecondOptional > 0:
+ fields = append([]string{defaults[0]}, fields...)
+ default:
+ return nil, fmt.Errorf("unknown optional field")
+ }
+ }
+
+ // Populate all fields not part of options with their defaults
+ n := 0
+ expandedFields := make([]string, len(places))
+ copy(expandedFields, defaults)
+ for i, place := range places {
+ if options&place > 0 {
+ expandedFields[i] = fields[n]
+ n++
+ }
+ }
+ return expandedFields, nil
+}
+
+var standardParser = NewParser(
+ Minute | Hour | Dom | Month | Dow | Descriptor,
+)
+
+// ParseStandard returns a new crontab schedule representing the given
+// standardSpec (https://en.wikipedia.org/wiki/Cron). It requires 5 entries
+// representing: minute, hour, day of month, month and day of week, in that
+// order. It returns a descriptive error if the spec is not valid.
+//
+// It accepts
+// - Standard crontab specs, e.g. "* * * * ?"
+// - Descriptors, e.g. "@midnight", "@every 1h30m"
+func ParseStandard(standardSpec string) (Schedule, error) {
+ return standardParser.Parse(standardSpec)
+}
+
+// getField returns an Int with the bits set representing all of the times that
+// the field represents or error parsing field value. A "field" is a comma-separated
+// list of "ranges".
+func getField(field string, r bounds) (uint64, error) {
+ var bits uint64
+ ranges := strings.FieldsFunc(field, func(r rune) bool { return r == ',' })
+ for _, expr := range ranges {
+ bit, err := getRange(expr, r)
+ if err != nil {
+ return bits, err
+ }
+ bits |= bit
+ }
+ return bits, nil
+}
+
+// getRange returns the bits indicated by the given expression:
+// number | number "-" number [ "/" number ]
+// or error parsing range.
+func getRange(expr string, r bounds) (uint64, error) {
+ var (
+ start, end, step uint
+ rangeAndStep = strings.Split(expr, "/")
+ lowAndHigh = strings.Split(rangeAndStep[0], "-")
+ singleDigit = len(lowAndHigh) == 1
+ err error
+ )
+
+ var extra uint64
+ if lowAndHigh[0] == "*" || lowAndHigh[0] == "?" {
+ start = r.min
+ end = r.max
+ extra = starBit
+ } else {
+ start, err = parseIntOrName(lowAndHigh[0], r.names)
+ if err != nil {
+ return 0, err
+ }
+ switch len(lowAndHigh) {
+ case 1:
+ end = start
+ case 2:
+ end, err = parseIntOrName(lowAndHigh[1], r.names)
+ if err != nil {
+ return 0, err
+ }
+ default:
+ return 0, fmt.Errorf("too many hyphens: %s", expr)
+ }
+ }
+
+ switch len(rangeAndStep) {
+ case 1:
+ step = 1
+ case 2:
+ step, err = mustParseInt(rangeAndStep[1])
+ if err != nil {
+ return 0, err
+ }
+
+ // Special handling: "N/step" means "N-max/step".
+ if singleDigit {
+ end = r.max
+ }
+ if step > 1 {
+ extra = 0
+ }
+ default:
+ return 0, fmt.Errorf("too many slashes: %s", expr)
+ }
+
+ if start < r.min {
+ return 0, fmt.Errorf("beginning of range (%d) below minimum (%d): %s", start, r.min, expr)
+ }
+ if end > r.max {
+ return 0, fmt.Errorf("end of range (%d) above maximum (%d): %s", end, r.max, expr)
+ }
+ if start > end {
+ return 0, fmt.Errorf("beginning of range (%d) beyond end of range (%d): %s", start, end, expr)
+ }
+ if step == 0 {
+ return 0, fmt.Errorf("step of range should be a positive number: %s", expr)
+ }
+
+ return getBits(start, end, step) | extra, nil
+}
+
+// parseIntOrName returns the (possibly-named) integer contained in expr.
+func parseIntOrName(expr string, names map[string]uint) (uint, error) {
+ if names != nil {
+ if namedInt, ok := names[strings.ToLower(expr)]; ok {
+ return namedInt, nil
+ }
+ }
+ return mustParseInt(expr)
+}
+
+// mustParseInt parses the given expression as an int or returns an error.
+func mustParseInt(expr string) (uint, error) {
+ num, err := strconv.Atoi(expr)
+ if err != nil {
+ return 0, fmt.Errorf("failed to parse int from %s: %s", expr, err)
+ }
+ if num < 0 {
+ return 0, fmt.Errorf("negative number (%d) not allowed: %s", num, expr)
+ }
+
+ return uint(num), nil
+}
+
+// getBits sets all bits in the range [min, max], modulo the given step size.
+func getBits(min, max, step uint) uint64 {
+ var bits uint64
+
+ // If step is 1, use shifts.
+ if step == 1 {
+ return ^(math.MaxUint64 << (max + 1)) & (math.MaxUint64 << min)
+ }
+
+ // Else, use a simple loop.
+ for i := min; i <= max; i += step {
+ bits |= 1 << i
+ }
+ return bits
+}
+
+// all returns all bits within the given bounds. (plus the star bit)
+func all(r bounds) uint64 {
+ return getBits(r.min, r.max, 1) | starBit
+}
+
+// parseDescriptor returns a predefined schedule for the expression, or error if none matches.
+func parseDescriptor(descriptor string, loc *time.Location) (Schedule, error) {
+ switch descriptor {
+ case "@yearly", "@annually":
+ return &SpecSchedule{
+ Second: 1 << seconds.min,
+ Minute: 1 << minutes.min,
+ Hour: 1 << hours.min,
+ Dom: 1 << dom.min,
+ Month: 1 << months.min,
+ Dow: all(dow),
+ Location: loc,
+ }, nil
+
+ case "@monthly":
+ return &SpecSchedule{
+ Second: 1 << seconds.min,
+ Minute: 1 << minutes.min,
+ Hour: 1 << hours.min,
+ Dom: 1 << dom.min,
+ Month: all(months),
+ Dow: all(dow),
+ Location: loc,
+ }, nil
+
+ case "@weekly":
+ return &SpecSchedule{
+ Second: 1 << seconds.min,
+ Minute: 1 << minutes.min,
+ Hour: 1 << hours.min,
+ Dom: all(dom),
+ Month: all(months),
+ Dow: 1 << dow.min,
+ Location: loc,
+ }, nil
+
+ case "@daily", "@midnight":
+ return &SpecSchedule{
+ Second: 1 << seconds.min,
+ Minute: 1 << minutes.min,
+ Hour: 1 << hours.min,
+ Dom: all(dom),
+ Month: all(months),
+ Dow: all(dow),
+ Location: loc,
+ }, nil
+
+ case "@hourly":
+ return &SpecSchedule{
+ Second: 1 << seconds.min,
+ Minute: 1 << minutes.min,
+ Hour: all(hours),
+ Dom: all(dom),
+ Month: all(months),
+ Dow: all(dow),
+ Location: loc,
+ }, nil
+
+ }
+
+ const every = "@every "
+ if strings.HasPrefix(descriptor, every) {
+ duration, err := time.ParseDuration(descriptor[len(every):])
+ if err != nil {
+ return nil, fmt.Errorf("failed to parse duration %s: %s", descriptor, err)
+ }
+ return Every(duration), nil
+ }
+
+ return nil, fmt.Errorf("unrecognized descriptor: %s", descriptor)
+}
diff --git a/vendor/github.com/robfig/cron/v3/spec.go b/vendor/github.com/robfig/cron/v3/spec.go
new file mode 100644
index 0000000000..fa1e241e5f
--- /dev/null
+++ b/vendor/github.com/robfig/cron/v3/spec.go
@@ -0,0 +1,188 @@
+package cron
+
+import "time"
+
+// SpecSchedule specifies a duty cycle (to the second granularity), based on a
+// traditional crontab specification. It is computed initially and stored as bit sets.
+type SpecSchedule struct {
+ Second, Minute, Hour, Dom, Month, Dow uint64
+
+ // Override location for this schedule.
+ Location *time.Location
+}
+
+// bounds provides a range of acceptable values (plus a map of name to value).
+type bounds struct {
+ min, max uint
+ names map[string]uint
+}
+
+// The bounds for each field.
+var (
+ seconds = bounds{0, 59, nil}
+ minutes = bounds{0, 59, nil}
+ hours = bounds{0, 23, nil}
+ dom = bounds{1, 31, nil}
+ months = bounds{1, 12, map[string]uint{
+ "jan": 1,
+ "feb": 2,
+ "mar": 3,
+ "apr": 4,
+ "may": 5,
+ "jun": 6,
+ "jul": 7,
+ "aug": 8,
+ "sep": 9,
+ "oct": 10,
+ "nov": 11,
+ "dec": 12,
+ }}
+ dow = bounds{0, 6, map[string]uint{
+ "sun": 0,
+ "mon": 1,
+ "tue": 2,
+ "wed": 3,
+ "thu": 4,
+ "fri": 5,
+ "sat": 6,
+ }}
+)
+
+const (
+ // Set the top bit if a star was included in the expression.
+ starBit = 1 << 63
+)
+
+// Next returns the next time this schedule is activated, greater than the given
+// time. If no time can be found to satisfy the schedule, return the zero time.
+func (s *SpecSchedule) Next(t time.Time) time.Time {
+ // General approach
+ //
+ // For Month, Day, Hour, Minute, Second:
+ // Check if the time value matches. If yes, continue to the next field.
+ // If the field doesn't match the schedule, then increment the field until it matches.
+ // While incrementing the field, a wrap-around brings it back to the beginning
+ // of the field list (since it is necessary to re-verify previous field
+ // values)
+
+ // Convert the given time into the schedule's timezone, if one is specified.
+ // Save the original timezone so we can convert back after we find a time.
+ // Note that schedules without a time zone specified (time.Local) are treated
+ // as local to the time provided.
+ origLocation := t.Location()
+ loc := s.Location
+ if loc == time.Local {
+ loc = t.Location()
+ }
+ if s.Location != time.Local {
+ t = t.In(s.Location)
+ }
+
+ // Start at the earliest possible time (the upcoming second).
+ t = t.Add(1*time.Second - time.Duration(t.Nanosecond())*time.Nanosecond)
+
+ // This flag indicates whether a field has been incremented.
+ added := false
+
+ // If no time is found within five years, return zero.
+ yearLimit := t.Year() + 5
+
+WRAP:
+ if t.Year() > yearLimit {
+ return time.Time{}
+ }
+
+ // Find the first applicable month.
+ // If it's this month, then do nothing.
+ for 1< 12 {
+ t = t.Add(time.Duration(24-t.Hour()) * time.Hour)
+ } else {
+ t = t.Add(time.Duration(-t.Hour()) * time.Hour)
+ }
+ }
+
+ if t.Day() == 1 {
+ goto WRAP
+ }
+ }
+
+ for 1< 0
+ dowMatch bool = 1< 0
+ )
+ if s.Dom&starBit > 0 || s.Dow&starBit > 0 {
+ return domMatch && dowMatch
+ }
+ return domMatch || dowMatch
+}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index fdd895811d..2fd1591192 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -306,6 +306,9 @@ github.com/prometheus/common/model
github.com/prometheus/procfs
github.com/prometheus/procfs/internal/fs
github.com/prometheus/procfs/internal/util
+# github.com/robfig/cron/v3 v3.0.1
+## explicit; go 1.12
+github.com/robfig/cron/v3
# github.com/russross/blackfriday/v2 v2.1.0
## explicit
github.com/russross/blackfriday/v2