Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Passthrough autopilot - Adds mutating webhook #3833

Merged
merged 17 commits into from
May 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions install/helm/agones/templates/extensions.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,54 @@ webhooks:
{{- end }}
{{- if not (default .Values.agones.controller.disableSecret .Values.agones.extensions.disableSecret) }}
---
apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata:
name: zzz-agones-mutation-webhook
{{- $annotations := default .Values.agones.controller.mutatingWebhook.annotations .Values.agones.extensions.mutatingWebhook.annotations }}
{{- if $annotations }}
annotations:
{{- toYaml $annotations | nindent 4 }}
{{- end }}
labels:
component: controller
app: {{ template "agones.name" . }}
chart: {{ template "agones.chart" . }}
release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
webhooks:
- name: mutations.agones.dev
admissionReviewVersions:
- v1
sideEffects: None
failurePolicy: Fail
clientConfig:
service:
name: agones-controller-service
namespace: {{ .Release.Namespace }}
path: /mutate
{{- if not .Values.agones.controller.mutatingWebhook.disableCaBundle }}
{{- if .Values.agones.controller.generateTLS }}
caBundle: {{ b64enc $ca.Cert }}
{{- else }}
caBundle: {{ default (.Files.Get "certs/server.crt") .Values.agones.controller.tlsCert | b64enc }}
{{- end }}
{{- end }}
objectSelector:
matchLabels:
agones.dev/port: "autopilot-passthrough"
rules:
- apiGroups:
- ""
resources:
- "pods"
apiVersions:
- "v1"
operations:
- CREATE
{{- end }}
{{- if not .Values.agones.controller.disableSecret }}
---
apiVersion: v1
kind: Secret
metadata:
Expand Down
36 changes: 36 additions & 0 deletions install/yaml/install.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17599,6 +17599,42 @@ webhooks:
- CREATE
- UPDATE
---
# Source: agones/templates/extensions.yaml
apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata:
name: zzz-agones-mutation-webhook
labels:
component: controller
app: agones
chart: agones-1.41.0-dev
release: agones-manual
heritage: Helm
webhooks:
- name: mutations.agones.dev
admissionReviewVersions:
- v1
sideEffects: None
failurePolicy: Fail
clientConfig:
service:
name: agones-controller-service
namespace: agones-system
path: /mutate
caBundle: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVjVENDQTFtZ0F3SUJBZ0lVRm5DOUsxT1kzRnFNaWhqN3RWbXh5R3hwUVdzd0RRWUpLb1pJaHZjTkFRRUwKQlFBd2dhb3hDekFKQmdOVkJBWVRBbFZUTVJNd0VRWURWUVFJREFwVGIyMWxMVk4wWVhSbE1ROHdEUVlEVlFRSwpEQVpCWjI5dVpYTXhEekFOQmdOVkJBc01Ca0ZuYjI1bGN6RTBNRElHQTFVRUF3d3JZV2R2Ym1WekxXTnZiblJ5CmIyeHNaWEl0YzJWeWRtbGpaUzVoWjI5dVpYTXRjM2x6ZEdWdExuTjJZekV1TUN3R0NTcUdTSWIzRFFFSkFSWWYKWVdkdmJtVnpMV1JwYzJOMWMzTkFaMjl2WjJ4bFozSnZkWEJ6TG1OdmJUQWVGdzB5TVRBMk16QXhPVFUyTWpGYQpGdzB6TVRBMk1qZ3hPVFUyTWpGYU1JR3FNUXN3Q1FZRFZRUUdFd0pWVXpFVE1CRUdBMVVFQ0F3S1UyOXRaUzFUCmRHRjBaVEVQTUEwR0ExVUVDZ3dHUVdkdmJtVnpNUTh3RFFZRFZRUUxEQVpCWjI5dVpYTXhOREF5QmdOVkJBTU0KSzJGbmIyNWxjeTFqYjI1MGNtOXNiR1Z5TFhObGNuWnBZMlV1WVdkdmJtVnpMWE41YzNSbGJTNXpkbU14TGpBcwpCZ2txaGtpRzl3MEJDUUVXSDJGbmIyNWxjeTFrYVhOamRYTnpRR2R2YjJkc1pXZHliM1Z3Y3k1amIyMHdnZ0VpCk1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRQ2dka0xPS0NINThLSkJpdEJqeVlyTDArRTkKdEl0TFhGVGdxQU9TMGdBQitSVXNZMGhicmVWRHd0SExKYXBnMG55Ni9UYTcvMEc1Wm9kaGR4RlFtS2JWMUxmWQpmZGR0Qm4vOGd4Wi9JQ2dRblU3N3RqY1pLV3JxaW4vZ3h3ZUJua3hjWEtrT3Z1MldoRHdZZVFLN3ZHNEljOGhzClZHb1hTZWo4US94d2M4a0FCRG04YVRSU1RUYmsyWi9kem9mUmswU2xrc1BrVWV5b0NwRGVGbERqY0tTcDAzWnUKV2dBUTNpVy83c1AxVFV5WEtnblZ5M2ZpWm1RQUZreEtOQkxVV0gvVEJJeWtMdUVCMmRYYUd0L0VpZzQ4SWpVOQpMYUxyM3JWSW1Dcmt6dlB5V3VEZTd6MmVKdDE3WEhoTFVHcnE4YTFUSFp3d1NSWUZRc29tQ09ORVNBSTdBZ01CCkFBR2pnWXd3Z1lrd0hRWURWUjBPQkJZRUZMa3FUUWNMQloyMUlWc3BGbkNiaS9TbGtUbzlNQjhHQTFVZEl3UVkKTUJhQUZMa3FUUWNMQloyMUlWc3BGbkNiaS9TbGtUbzlNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdOZ1lEVlIwUgpCQzh3TFlJcllXZHZibVZ6TFdOdmJuUnliMnhzWlhJdGMyVnlkbWxqWlM1aFoyOXVaWE10YzNsemRHVnRMbk4yCll6QU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFWQTUxU3dNcEhZY20zUnRuc2I5MkgwUTZYT1ZndEJzSWRaY1QKbFBuSmFBSGdybEt2SnhiMU0rdTdQYllDZkZOTWlUTStyWGZ5cWtJRXY3VU1aN0dWeS9CYm9zTk1sb2M0UHJjaAo3RnVlai9zVnArcW1GT1c0VzlPVTFwcytqWm5vcHJ4Z3R1OVgzbmpBZjZiWWVqQWMzaVo0Q0xpem8vMDd2Qk94CnA5L3J4R0FjSVVjQW04Y3hXa01kaEduNnZOYkNFcXJoVTRJdnZSYlMwVnlrckhPY3RGM25raC9GbnRHQU80RDEKUEgrUThSQXBNK2xBeGtXcFIvNXlHTXdLM05WcS9kc2JaclQ5RHhId0hUU2tqL3JXZVRrWmxIN042MHpZL3JqbwpNUjBJNEtOWHl3WElTcGdNbE93dkxPdGY2aUNYeHJDNyt1RjdyQmxCei9tSUNxYnR0dz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
objectSelector:
matchLabels:
agones.dev/port: "autopilot-passthrough"
rules:
- apiGroups:
- ""
resources:
- "pods"
apiVersions:
- "v1"
operations:
- CREATE
---
# Source: agones/templates/priority-class.yaml
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
Expand Down
21 changes: 19 additions & 2 deletions pkg/cloudproduct/gke/gke.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,10 +134,18 @@ func (*gkeAutopilot) NewPortAllocator(portRanges map[string]portallocator.PortRa

func (*gkeAutopilot) WaitOnFreePorts() bool { return true }

func checkPassthroughPortPolicy(portPolicy agonesv1.PortPolicy) bool {
// if feature is not enabled and port is Passthrough return true because that should be an invalid port
// if feature is not enabled and port is not Passthrough you can return false because there's no error but check for None port
// if feature is enabled and port is passthrough return false because there is no error
// if feature is enabled and port is not passthrough return false because there is no error but check for None port
return (!runtime.FeatureEnabled(runtime.FeatureAutopilotPassthroughPort) && portPolicy == agonesv1.Passthrough) || portPolicy == agonesv1.Static
}

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 || !runtime.FeatureEnabled(runtime.FeaturePortPolicyNone)) {
if p.PortPolicy != agonesv1.Dynamic && (p.PortPolicy != agonesv1.None || !runtime.FeatureEnabled(runtime.FeaturePortPolicyNone)) && checkPassthroughPortPolicy(p.PortPolicy) {
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 || !runtime.FeatureEnabled(runtime.FeaturePortPolicyNone)) {
Expand Down Expand Up @@ -256,14 +264,23 @@ type autopilotPortAllocator struct {
func (*autopilotPortAllocator) Run(_ context.Context) error { return nil }
func (*autopilotPortAllocator) DeAllocate(gs *agonesv1.GameServer) {}

func checkPassthroughPortPolicyForAutopilot(portPolicy agonesv1.PortPolicy) bool {
// Autopilot can have Dynamic or Passthrough
// if feature is not enabled and port is Passthrough -> true
// if feature is not enabled and port is not Passthrough -> true
// if feature is enabled and port is Passthrough -> false
// if feature is enabled and port is not Passthrough -> true
return !(runtime.FeatureEnabled(runtime.FeatureAutopilotPassthroughPort) && portPolicy == agonesv1.Passthrough)
}

func (apa *autopilotPortAllocator) Allocate(gs *agonesv1.GameServer) *agonesv1.GameServer {
if len(gs.Spec.Ports) == 0 {
return gs // Nothing to do.
}

var ports []agonesv1.GameServerPort
for i, p := range gs.Spec.Ports {
if p.PortPolicy != agonesv1.Dynamic {
if p.PortPolicy != agonesv1.Dynamic && checkPassthroughPortPolicyForAutopilot(p.PortPolicy) {
logger.WithField("gs", gs.Name).WithField("portPolicy", p.PortPolicy).Error(
"GameServer has invalid PortPolicy for Autopilot - this should have been rejected by webhooks. Refusing to assign ports.")
return gs
Expand Down
Loading
Loading