Skip to content

Commit

Permalink
PortPolicyNone feature gate
Browse files Browse the repository at this point in the history
  • Loading branch information
daniellee committed May 13, 2024
1 parent 51cd873 commit 6d44639
Show file tree
Hide file tree
Showing 15 changed files with 3,668 additions and 3,593 deletions.
2 changes: 1 addition & 1 deletion build/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ GS_TEST_IMAGE ?= us-docker.pkg.dev/agones-images/examples/simple-game-server:0.3
BETA_FEATURE_GATES ?= "CountsAndLists=true&DisableResyncOnSDKServer=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&Example=true"
ALPHA_FEATURE_GATES ?= "PlayerAllocationFilter=true&PlayerTracking=true&RollingUpdateFix=true&PortRanges=true&PortPolicyNone=true&Example=true"

# Build with Windows support
WITH_WINDOWS=1
Expand Down
2 changes: 1 addition & 1 deletion cloudbuild.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ steps:
declare -A versionsAndRegions=( [1.27]=us-east1 [1.28]=us-west1 [1.29]=europe-west1 )
# Keep in sync with (the inverse of) pkg/util/runtime/features.go:featureDefaults
featureWithGate="PlayerAllocationFilter=true&PlayerTracking=true&CountsAndLists=false&RollingUpdateFix=true&PortRanges=true&DisableResyncOnSDKServer=false&Example=true"
featureWithGate="PlayerAllocationFilter=true&PlayerTracking=true&CountsAndLists=false&RollingUpdateFix=true&PortRanges=true&PortPolicyNone=true&DisableResyncOnSDKServer=false&Example=true"
featureWithoutGate=""
# Use this if specific feature gates can only be supported on specific Kubernetes versions.
Expand Down
2 changes: 2 additions & 0 deletions examples/gameserver.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ spec:
# port is available. When static is the policy specified, `hostPort` is required to be populated
# - "Passthrough" dynamically sets the `containerPort` to the same value as the dynamically selected hostPort.
# This will mean that users will need to lookup what port has been opened through the server side SDK.
# [Stage:Alpha]
# [FeatureFlag:PortPolicyNone]
# - "None" means the `hostPort` is ignored and if defined, the `containerPort` (optional) is used to set the port on the GameServer instance.
portPolicy: Dynamic
# The name of the container to open the port on. Defaults to the game server container if omitted or empty.
Expand Down
4 changes: 4 additions & 0 deletions examples/simple-game-server/gameserver-none.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
# 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:Alpha]
# [FeatureFlag:PortPolicyNone]
# - "None" means the `hostPort` is ignored and if defined, the `containerPort` (optional) is used to set the port on the GameServer instance.
apiVersion: agones.dev/v1
kind: GameServer
metadata:
Expand Down
1 change: 1 addition & 0 deletions install/helm/agones/defaultfeaturegates.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ PlayerAllocationFilter: false
PlayerTracking: false
RollingUpdateFix: false
PortRanges: false
PortPolicyNone: false

# Dev features
FeatureAutopilotPassthroughPort: false
Expand Down
8 changes: 6 additions & 2 deletions pkg/apis/agones/v1/gameserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,9 @@ type GameServerPort struct {
// 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.
// `Passthrough` dynamically sets the `containerPort` to the same value as the dynamically selected hostPort.
PortPolicy PortPolicy `json:"portPolicy,omitempty"`
// Container is the name of the container on which to open the port. Defaults to the game server container.
// +optional
Expand Down Expand Up @@ -743,7 +746,8 @@ func (gs *GameServer) Pod(apiHooks APIHooks, sidecars ...corev1.Container) (*cor
gs.podObjectMeta(pod)
for _, p := range gs.Spec.Ports {
var hostPort int32
if p.PortPolicy != None {

if !runtime.FeatureEnabled(runtime.FeaturePortPolicyNone) || p.PortPolicy != None {
hostPort = p.HostPort
}

Expand Down Expand Up @@ -860,7 +864,7 @@ func (gs *GameServer) HasPortPolicy(policy PortPolicy) bool {

// Status returns a GameServerStatusPort for this GameServerPort
func (p GameServerPort) Status() GameServerStatusPort {
if p.PortPolicy == None {
if runtime.FeatureEnabled(runtime.FeaturePortPolicyNone) && p.PortPolicy == None {
return GameServerStatusPort{Name: p.Name, Port: p.ContainerPort}
}

Expand Down
9 changes: 7 additions & 2 deletions pkg/apis/agones/v1/gameserver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ func TestStatus(t *testing.T) {
expected: GameServerStatusPort{Name: "test-name", Port: 7777},
},
}
runtime.FeatureTestMutex.Lock()
defer runtime.FeatureTestMutex.Unlock()
require.NoError(t, runtime.ParseFeatures(string(runtime.FeaturePortPolicyNone)+"=true"))

for _, tc := range testCases {
name := "test-name"
Expand Down Expand Up @@ -1527,8 +1530,10 @@ func TestGameServerCountPortsForRange(t *testing.T) {
}

func TestGameServerPatch(t *testing.T) {
fixture := &GameServer{ObjectMeta: metav1.ObjectMeta{Name: "lucy", ResourceVersion: "1234"},
Spec: GameServerSpec{Container: "goat"}}
fixture := &GameServer{
ObjectMeta: metav1.ObjectMeta{Name: "lucy", ResourceVersion: "1234"},
Spec: GameServerSpec{Container: "goat"},
}

delta := fixture.DeepCopy()
delta.Spec.Container = "bear"
Expand Down
9 changes: 9 additions & 0 deletions pkg/client/applyconfiguration/agones/v1/gameserverport.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion pkg/cloudproduct/gke/gke.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ func (*gkeAutopilot) WaitOnFreePorts() bool { return true }
func (g *gkeAutopilot) ValidateGameServerSpec(gss *agonesv1.GameServerSpec, fldPath *field.Path) field.ErrorList {
allErrs := g.ValidateScheduling(gss.Scheduling, fldPath.Child("scheduling"))
for i, p := range gss.Ports {
if p.PortPolicy != agonesv1.Dynamic && p.PortPolicy != agonesv1.None {
if p.PortPolicy != agonesv1.Dynamic && (p.PortPolicy != agonesv1.None || !runtime.FeatureEnabled(runtime.FeaturePortPolicyNone)) {
allErrs = append(allErrs, field.Invalid(fldPath.Child("ports").Index(i).Child("portPolicy"), string(p.PortPolicy), errPortPolicyMustBeDynamicOrNone))
}
if p.Range != agonesv1.DefaultPortRange && p.PortPolicy != agonesv1.None {
Expand Down
5 changes: 5 additions & 0 deletions pkg/cloudproduct/gke/gke_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,11 @@ func TestValidateGameServer(t *testing.T) {
},
} {
t.Run(name, func(t *testing.T) {
// PortPolicy None is behind a feature flag
runtime.FeatureTestMutex.Lock()
defer runtime.FeatureTestMutex.Unlock()
require.NoError(t, runtime.ParseFeatures(string(runtime.FeaturePortPolicyNone)+"=true"))

causes := (&gkeAutopilot{useExtendedDurationPods: tc.edPods}).ValidateGameServerSpec(&agonesv1.GameServerSpec{
Ports: tc.ports,
Scheduling: tc.scheduling,
Expand Down
5 changes: 5 additions & 0 deletions pkg/gameservers/gameservers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,11 @@ func TestApplyGameServerAddressAndPort(t *testing.T) {
pod.Status.PodIPs = []corev1.PodIP{{IP: ipFixture}}
tc.podMod(pod)

// PortPolicy None is behind a feature flag
runtime.FeatureTestMutex.Lock()
defer runtime.FeatureTestMutex.Unlock()
require.NoError(t, runtime.ParseFeatures(string(runtime.FeaturePortPolicyNone)+"=true"))

gs, err := applyGameServerAddressAndPort(gsFixture, node, pod, tc.podSyncer)
require.NoError(t, err)
if assert.NotEmpty(t, gs.Spec.Ports) {
Expand Down
4 changes: 4 additions & 0 deletions pkg/util/runtime/features.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ const (
// FeaturePortRanges is a feature flag to enable/disable specific port ranges.
FeaturePortRanges Feature = "PortRanges"

// FeaturePortPolicyNone is a feature flag to allow setting Port Policy to None.
FeaturePortPolicyNone Feature = "PortPolicyNone"

////////////////
// Dev features

Expand Down Expand Up @@ -118,6 +121,7 @@ var (
FeaturePlayerTracking: false,
FeatureRollingUpdateFix: false,
FeaturePortRanges: false,
FeaturePortPolicyNone: false,

// Dev features
FeatureAutopilotPassthroughPort: false,
Expand Down
1 change: 1 addition & 0 deletions site/content/en/docs/Guides/feature-stages.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ The current set of `alpha` and `beta` feature gates:
| [Player Tracking]({{< ref "/docs/Guides/player-tracking.md" >}}) | `PlayerTracking` | Disabled | `Alpha` | 1.6.0 |
| [Rolling Update Fixes](https://github.com/googleforgames/agones/issues/3688) | `RollingUpdateFix` | Disabled | `Alpha` | 1.41.0 |
| [Multiple dynamic port ranges](https://github.com/googleforgames/agones/issues/1911) | `PortRanges` | Disabled | `Alpha` | 1.41.0 |
| [Port Policy None](https://github.com/googleforgames/agones/issues/3804) | `PortPolicyNone` | Disabled | `Alpha` | 1.41.0 |
| Example Gate (not in use) | `Example` | Disabled | None | 0.13.0 |

[fleet-updates]: {{% relref "./fleet-updates.md#notifying-gameservers-on-fleet-updatedownscale" %}}
Expand Down
Loading

0 comments on commit 6d44639

Please sign in to comment.