From 9e74cc5e6fc30bbc7f78d2f797b618a3a10750e2 Mon Sep 17 00:00:00 2001 From: Ermin Hrkalovic Date: Mon, 21 Oct 2024 21:01:23 +0200 Subject: [PATCH] add metadata to agones webhook autoscaler request --- build/Makefile | 2 +- cloudbuild.yaml | 2 +- install/helm/agones/defaultfeaturegates.yaml | 1 + pkg/apis/autoscaling/v1/fleetautoscaler.go | 2 + pkg/fleetautoscalers/fleetautoscalers.go | 9 ++++ pkg/fleetautoscalers/fleetautoscalers_test.go | 45 +++++++++++++++++++ pkg/util/runtime/features.go | 16 ++++--- .../en/docs/Reference/fleetautoscaler.md | 2 + 8 files changed, 71 insertions(+), 8 deletions(-) diff --git a/build/Makefile b/build/Makefile index 3a8d6fb39b..21ceec6279 100644 --- a/build/Makefile +++ b/build/Makefile @@ -70,7 +70,7 @@ GS_TEST_IMAGE ?= us-docker.pkg.dev/agones-images/examples/simple-game-server:0.3 BETA_FEATURE_GATES ?= "AutopilotPassthroughPort=true&CountsAndLists=true&DisableResyncOnSDKServer=true&GKEAutopilotExtendedDurationPods=true" # Enable all alpha feature gates. Keep in sync with `false` (alpha) entries in pkg/util/runtime/features.go:featureDefaults -ALPHA_FEATURE_GATES ?= "PlayerAllocationFilter=true&PlayerTracking=true&RollingUpdateFix=true&PortRanges=true&PortPolicyNone=true&ScheduledAutoscaler=true&Example=true" +ALPHA_FEATURE_GATES ?= "PlayerAllocationFilter=true&FleetAutoscaleRequestMetaData=true&PlayerTracking=true&RollingUpdateFix=true&PortRanges=true&PortPolicyNone=true&ScheduledAutoscaler=true&Example=true" # Build with Windows support WITH_WINDOWS=1 diff --git a/cloudbuild.yaml b/cloudbuild.yaml index 7616bde94a..34707e023b 100644 --- a/cloudbuild.yaml +++ b/cloudbuild.yaml @@ -274,7 +274,7 @@ steps: declare -A versionsAndRegions=( [1.28]=us-west1 [1.29]=europe-west1 [1.30]=asia-east1 ) # Keep in sync with (the inverse of) pkg/util/runtime/features.go:featureDefaults - featureWithGate="PlayerAllocationFilter=true&PlayerTracking=true&CountsAndLists=false&RollingUpdateFix=true&PortRanges=true&PortPolicyNone=true&ScheduledAutoscaler=true&DisableResyncOnSDKServer=false&AutopilotPassthroughPort=false&GKEAutopilotExtendedDurationPods=false&Example=true" + featureWithGate="PlayerAllocationFilter=true&FleetAutoscaleRequestMetaData=true&PlayerTracking=true&CountsAndLists=false&RollingUpdateFix=true&PortRanges=true&PortPolicyNone=true&ScheduledAutoscaler=true&DisableResyncOnSDKServer=false&AutopilotPassthroughPort=false&GKEAutopilotExtendedDurationPods=false&Example=true" featureWithoutGate="" # Use this if specific feature gates can only be supported on specific Kubernetes versions. diff --git a/install/helm/agones/defaultfeaturegates.yaml b/install/helm/agones/defaultfeaturegates.yaml index 36eb5c1b75..1528804e7d 100644 --- a/install/helm/agones/defaultfeaturegates.yaml +++ b/install/helm/agones/defaultfeaturegates.yaml @@ -21,6 +21,7 @@ CountsAndLists: true DisableResyncOnSDKServer: true # Alpha features +FleetAutoscaleRequestMetaData: false PlayerAllocationFilter: false PlayerTracking: false RollingUpdateFix: false diff --git a/pkg/apis/autoscaling/v1/fleetautoscaler.go b/pkg/apis/autoscaling/v1/fleetautoscaler.go index 14e96c4447..c4972cb73d 100644 --- a/pkg/apis/autoscaling/v1/fleetautoscaler.go +++ b/pkg/apis/autoscaling/v1/fleetautoscaler.go @@ -316,6 +316,8 @@ type FleetAutoscaleRequest struct { Namespace string `json:"namespace"` // The Fleet's status values Status agonesv1.FleetStatus `json:"status"` + // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. + MetaData *metav1.ObjectMeta `json:"metadata,omitempty"` } // FleetAutoscaleResponse defines the response of webhook autoscaler endpoint diff --git a/pkg/fleetautoscalers/fleetautoscalers.go b/pkg/fleetautoscalers/fleetautoscalers.go index 8663be99ad..9b29913544 100644 --- a/pkg/fleetautoscalers/fleetautoscalers.go +++ b/pkg/fleetautoscalers/fleetautoscalers.go @@ -30,6 +30,7 @@ import ( "github.com/pkg/errors" "github.com/robfig/cron/v3" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/apimachinery/pkg/util/uuid" @@ -172,6 +173,14 @@ func applyWebhookPolicy(w *autoscalingv1.WebhookPolicy, f *agonesv1.Fleet) (repl Response: nil, } + if runtime.FeatureEnabled(runtime.FeatureFleetAutoscaleRequestMetaData) { + faReq.Request.MetaData = &metav1.ObjectMeta{ + Name: f.ObjectMeta.Name, + Labels: f.ObjectMeta.Labels, + Annotations: f.ObjectMeta.Annotations, + } + } + b, err := json.Marshal(faReq) if err != nil { return 0, false, err diff --git a/pkg/fleetautoscalers/fleetautoscalers_test.go b/pkg/fleetautoscalers/fleetautoscalers_test.go index 48a27b3588..dc7fa6640e 100644 --- a/pkg/fleetautoscalers/fleetautoscalers_test.go +++ b/pkg/fleetautoscalers/fleetautoscalers_test.go @@ -22,6 +22,7 @@ import ( "io" "net/http" "net/http/httptest" + "strconv" "testing" "time" @@ -92,6 +93,15 @@ func (t testServer) ServeHTTP(w http.ResponseWriter, r *http.Request) { faResp.Replicas = faReq.Status.Replicas * scaleFactor } + // override value for tests + if faReq.MetaData != nil { + if value, ok := faReq.MetaData.Annotations["fixedReplicas"]; ok { + faResp.Scale = true + replicas, _ := strconv.Atoi(value) + faResp.Replicas = int32(replicas) + } + } + review := &autoscalingv1.FleetAutoscaleReview{ Request: faReq, Response: &faResp, @@ -579,6 +589,41 @@ func TestApplyWebhookPolicy(t *testing.T) { } } +func TestApplyWebhookPolicyWithMetadata(t *testing.T) { + t.Parallel() + + utilruntime.FeatureTestMutex.Lock() + defer utilruntime.FeatureTestMutex.Unlock() + + err := utilruntime.ParseFeatures(string(utilruntime.FeatureFleetAutoscaleRequestMetaData) + "=true") + assert.NoError(t, err) + defer func() { + _ = utilruntime.ParseFeatures("") + }() + + ts := testServer{} + server := httptest.NewServer(ts) + defer server.Close() + + _, fleet := defaultWebhookFixtures() + + fixedReplicas := int32(11) + fleet.ObjectMeta.Annotations = map[string]string{ + "fixedReplicas": fmt.Sprintf("%d", fixedReplicas), + } + + webhookPolicy := &autoscalingv1.WebhookPolicy{ + Service: nil, + URL: &(server.URL), + } + + replicas, limited, err := applyWebhookPolicy(webhookPolicy, fleet) + + assert.Nil(t, err) + assert.False(t, limited) + assert.Equal(t, fixedReplicas, replicas) +} + func TestApplyWebhookPolicyNilFleet(t *testing.T) { t.Parallel() diff --git a/pkg/util/runtime/features.go b/pkg/util/runtime/features.go index fbbe49035c..e3a3ade6e2 100644 --- a/pkg/util/runtime/features.go +++ b/pkg/util/runtime/features.go @@ -48,6 +48,9 @@ const ( //////////////// // Alpha features + // FeatureFleetAutoscaleRequestMetaData is a feature flag that enables/disables fleet metadata on webhook autoscaler request. + FeatureFleetAutoscaleRequestMetaData Feature = "FleetAutoscaleRequestMetaData" + // FeaturePlayerAllocationFilter is a feature flag that enables the ability for Allocations to filter based on // player capacity. FeaturePlayerAllocationFilter Feature = "PlayerAllocationFilter" @@ -134,12 +137,13 @@ var ( FeatureDisableResyncOnSDKServer: true, // Alpha features - FeaturePlayerAllocationFilter: false, - FeaturePlayerTracking: false, - FeatureRollingUpdateFix: false, - FeaturePortRanges: false, - FeaturePortPolicyNone: false, - FeatureScheduledAutoscaler: false, + FeatureFleetAutoscaleRequestMetaData: false, + FeaturePlayerAllocationFilter: false, + FeaturePlayerTracking: false, + FeatureRollingUpdateFix: false, + FeaturePortRanges: false, + FeaturePortPolicyNone: false, + FeatureScheduledAutoscaler: false, // Dev features diff --git a/site/content/en/docs/Reference/fleetautoscaler.md b/site/content/en/docs/Reference/fleetautoscaler.md index 8eb3f83c30..3d04176814 100644 --- a/site/content/en/docs/Reference/fleetautoscaler.md +++ b/site/content/en/docs/Reference/fleetautoscaler.md @@ -374,6 +374,8 @@ type FleetAutoscaleRequest struct { Namespace string `json:"namespace"` // The Fleet's status values Status v1.FleetStatus `json:"status"` + // Standard object metadata; More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata. + MetaData *metav1.ObjectMeta `json:"metadata,omitempty"` } type FleetAutoscaleResponse struct {