diff --git a/cmd/controller/main.go b/cmd/controller/main.go index 48b70d30ac..8c16962eb9 100644 --- a/cmd/controller/main.go +++ b/cmd/controller/main.go @@ -21,13 +21,11 @@ import ( "os" "path/filepath" "strings" - "sync" "time" "agones.dev/agones/pkg" "agones.dev/agones/pkg/client/clientset/versioned" "agones.dev/agones/pkg/client/informers/externalversions" - "agones.dev/agones/pkg/fleetallocation" "agones.dev/agones/pkg/fleetautoscalers" "agones.dev/agones/pkg/fleets" "agones.dev/agones/pkg/gameserverallocations" @@ -45,7 +43,7 @@ import ( "github.com/sirupsen/logrus" "github.com/spf13/pflag" "github.com/spf13/viper" - lumberjack "gopkg.in/natefinch/lumberjack.v2" + "gopkg.in/natefinch/lumberjack.v2" extclientset "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" "k8s.io/apimachinery/pkg/api/resource" "k8s.io/client-go/informers" @@ -186,8 +184,6 @@ func main() { server.Handle("/", health) - allocationMutex := &sync.Mutex{} - gsCounter := gameservers.NewPerNodeCounter(kubeInformerFactory, agonesInformerFactory) gsController := gameservers.NewController(wh, health, @@ -197,15 +193,13 @@ func main() { gsSetController := gameserversets.NewController(wh, health, gsCounter, kubeClient, extClient, agonesClient, agonesInformerFactory) fleetController := fleets.NewController(wh, health, kubeClient, extClient, agonesClient, agonesInformerFactory) - faController := fleetallocation.NewController(wh, allocationMutex, - kubeClient, extClient, agonesClient, agonesInformerFactory) gasController := gameserverallocations.NewController(api, health, gsCounter, topNGSForAllocation, kubeClient, kubeInformerFactory, agonesClient, agonesInformerFactory) fasController := fleetautoscalers.NewController(wh, health, kubeClient, extClient, agonesClient, agonesInformerFactory) rs = append(rs, - httpsServer, gsCounter, gsController, gsSetController, fleetController, faController, fasController, gasController, server) + httpsServer, gsCounter, gsController, gsSetController, fleetController, fasController, gasController, server) stop := signals.NewStopChannel() diff --git a/examples/allocator-service/dockerfile b/examples/allocator-service/Dockerfile similarity index 100% rename from examples/allocator-service/dockerfile rename to examples/allocator-service/Dockerfile diff --git a/examples/allocator-service/README.md b/examples/allocator-service/README.md index 2be0823a9b..4564c3e328 100644 --- a/examples/allocator-service/README.md +++ b/examples/allocator-service/README.md @@ -1,10 +1,10 @@ # Simple Allocator Service -This service provides an example of using the [Agones API](https://godoc.org/agones.dev/agones/pkg/client/clientset/versioned/typed/stable/v1alpha1) to allocate a GameServer from a Fleet, and is used in the [Create an Allocator Service (Go)](../../docs/create_allocator_service.md) tutorial. +This service provides an example of using the [Agones API](https://godoc.org/agones.dev/agones/pkg/client/clientset/versioned/typed/stable/v1alpha1) to allocate a GameServer from a Fleet, and is used in the [Create an Allocator Service (Go)](https://agones.dev/site/docs/tutorials/allocator-service-go/) tutorial. ## Allocator Service -The service exposes an endpoint which allows client calls to FleetAllocationInterface.Create() over a secure connection. It also provides examples of how to create a service account with the least necessary privileges, how to create an Ingress, and how services can use secrets specific to their respective accounts. +The service exposes an endpoint which allows client calls to AllocationInterface.Create() over a secure connection. It also provides examples of how to create a service account with the least necessary privileges, how to create an Ingress, and how services can use secrets specific to their respective accounts. When the endpoint is called and a GameServer is allocated, it returns the JSON encoded GameServerStatus of the freshly allocated GameServer. -To learn how to deploy this allocator service to GKE, please see the tutorial [Create an Allocator Service (Go)](../../docs/create_allocator_service.md). +To learn how to deploy this allocator service to GKE, please see the tutorial [Create an Allocator Service (Go)](https://agones.dev/site/docs/tutorials/allocator-service-go/). diff --git a/examples/allocator-service/main.go b/examples/allocator-service/main.go index a1fa844cbf..0cfac4e981 100644 --- a/examples/allocator-service/main.go +++ b/examples/allocator-service/main.go @@ -6,17 +6,17 @@ import ( "io" "net/http" - "agones.dev/agones/pkg/apis/stable/v1alpha1" + allocationv1alpha1 "agones.dev/agones/pkg/apis/allocation/v1alpha1" + stablev1alpha1 "agones.dev/agones/pkg/apis/stable/v1alpha1" "agones.dev/agones/pkg/client/clientset/versioned" "agones.dev/agones/pkg/util/runtime" // for the logger - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/rest" ) // Constants which define the fleet and namespace we are using const namespace = "default" const fleetname = "simple-udp" -const generatename = "simple-udp-" // Variables for the logger and Agones Clientset var ( @@ -29,7 +29,7 @@ type handler func(w http.ResponseWriter, r *http.Request) // The structure of the json response type result struct { - Status v1alpha1.GameServerStatus `json:"status"` + Status allocationv1alpha1.GameServerAllocationState `json:"status"` } // Main will set up an http server and three endpoints @@ -119,8 +119,7 @@ func handleAddress(w http.ResponseWriter, r *http.Request) { http.Error(w, err.Error(), http.StatusInternalServerError) } w.Header().Set("Content-Type", "application/json") - result, _ := json.Marshal(&result{status}) - _, err = io.WriteString(w, string(result)) + err = json.NewEncoder(w).Encode(&result{status}) if err != nil { logger.WithError(err).Fatal("Error writing json from /address") } @@ -131,7 +130,7 @@ func checkReadyReplicas() int32 { // Get a FleetInterface for this namespace fleetInterface := agonesClient.StableV1alpha1().Fleets(namespace) // Get our fleet - fleet, err := fleetInterface.Get(fleetname, v1.GetOptions{}) + fleet, err := fleetInterface.Get(fleetname, metav1.GetOptions{}) if err != nil { logger.WithError(err).Info("Get fleet failed") } @@ -140,45 +139,39 @@ func checkReadyReplicas() int32 { } // Move a replica from ready to allocated and return the GameServerStatus -func allocate() (v1alpha1.GameServerStatus, error) { - var result v1alpha1.GameServerStatus - - // Log the values used in the fleet allocation - logger.WithField("namespace", namespace).Info("namespace for fa") - logger.WithField("generatename", generatename).Info("generatename for fa") - logger.WithField("fleetname", fleetname).Info("fleetname for fa") +func allocate() (allocationv1alpha1.GameServerAllocationState, error) { + // Log the values used in the allocation + logger.WithField("namespace", namespace).Info("namespace for gsa") + logger.WithField("fleetname", fleetname).Info("fleetname for gsa") // Find out how many ready replicas the fleet has - we need at least one readyReplicas := checkReadyReplicas() - logger.WithField("readyReplicas", readyReplicas).Info("numer of ready replicas") + logger.WithField("readyReplicas", readyReplicas).Info("number of ready replicas") // Log and return an error if there are no ready replicas if readyReplicas < 1 { logger.WithField("fleetname", fleetname).Info("Insufficient ready replicas, cannot create fleet allocation") - return result, errors.New("Insufficient ready replicas, cannot create fleet allocation") + return allocationv1alpha1.GameServerAllocationUnAllocated, errors.New("insufficient ready replicas, cannot create fleet allocation") } - // Get a FleetAllocationInterface for this namespace - fleetAllocationInterface := agonesClient.StableV1alpha1().FleetAllocations(namespace) + // Get a AllocationInterface for this namespace + allocationInterface := agonesClient.AllocationV1alpha1().GameServerAllocations(namespace) - // Define the fleet allocation using the constants set earlier - fa := &v1alpha1.FleetAllocation{ - ObjectMeta: v1.ObjectMeta{ - GenerateName: generatename, Namespace: namespace, - }, - Spec: v1alpha1.FleetAllocationSpec{FleetName: fleetname}, - } + // Define the allocation using the constants set earlier + gsa := &allocationv1alpha1.GameServerAllocation{ + Spec: allocationv1alpha1.GameServerAllocationSpec{ + Required: metav1.LabelSelector{MatchLabels: map[string]string{stablev1alpha1.FleetNameLabel: fleetname}}, + }} - // Create a new fleet allocation - newFleetAllocation, err := fleetAllocationInterface.Create(fa) + // Create a new allocation + gsa, err := allocationInterface.Create(gsa) if err != nil { // Log and return the error if the call to Create fails - logger.WithError(err).Info("Failed to create fleet allocation") - return result, errors.New("Failed to ceate fleet allocation") + logger.WithError(err).Info("Failed to create allocation") + return allocationv1alpha1.GameServerAllocationUnAllocated, errors.New("failed to create allocation") } // Log the GameServer.Staus of the new allocation, then return those values - logger.Info("New GameServer allocated: ", newFleetAllocation.Status.GameServer.Status) - result = newFleetAllocation.Status.GameServer.Status - return result, nil + logger.Info("New GameServer allocated: ", gsa.Status.State) + return gsa.Status.State, nil } diff --git a/examples/allocator-service/service-account.yaml b/examples/allocator-service/service-account.yaml index b46b228913..d69cf14458 100644 --- a/examples/allocator-service/service-account.yaml +++ b/examples/allocator-service/service-account.yaml @@ -10,11 +10,11 @@ rules: - apiGroups: [""] resources: ["events"] verbs: ["create"] -- apiGroups: ["stable.agones.dev"] - resources: ["fleetallocations"] +- apiGroups: ["allocation.agones.dev"] + resources: ["gameserverallocations"] verbs: ["create"] - apiGroups: ["stable.agones.dev"] - resources: [fleets, fleet"] + resources: ["fleets"] verbs: ["get"] --- diff --git a/examples/fleet.yaml b/examples/fleet.yaml index f5cbae99d1..397d8ad54e 100644 --- a/examples/fleet.yaml +++ b/examples/fleet.yaml @@ -15,7 +15,7 @@ # # Full example of a Fleet resource - a set of warm GameServers # that are available to be allocated from. -# To allocate a GameServer from a Fleet, use a FleetAllocation +# To allocate a GameServer from a Fleet, use a GameServerAllocation # apiVersion: "stable.agones.dev/v1alpha1" diff --git a/examples/fleetallocation.yaml b/examples/fleetallocation.yaml deleted file mode 100644 index 25d1a7477b..0000000000 --- a/examples/fleetallocation.yaml +++ /dev/null @@ -1,40 +0,0 @@ -# Copyright 2018 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. - -# -# Full example of a FleetAllocation - this is used to allocate a GameServer -# out of a Fleet so it can be handed to a set of players to play on. -# - -# (Deprecated; Look at gameserverallocation.yaml instead) - -apiVersion: "stable.agones.dev/v1alpha1" -kind: FleetAllocation -metadata: - # FleetAllocation Metadata - # https://v1-9.docs.kubernetes.io/docs/reference/generated/kubernetes-api/v1.9/#objectmeta-v1-meta - # We recommend using the following to generate a unique name when creating FleetAllocations - # This will need to be created with `kubectl create` if using the command line tooling - generateName: fleet-allocation-example- -spec: - # The name of the fleet to allocate from. Must be an existing Fleet in the same namespace - # as this FleetAllocation - fleetName: fleet-example - # Custom metadata that is added to game server status in the moment of allocation - # You can use this to tell the server necessary session data - metadata: - labels: - mode: deathmatch - annotations: - map: garden22 diff --git a/examples/simple-udp/fleetallocation.yaml b/examples/simple-udp/fleetallocation.yaml deleted file mode 100644 index 758a31fe62..0000000000 --- a/examples/simple-udp/fleetallocation.yaml +++ /dev/null @@ -1,24 +0,0 @@ -# Copyright 2018 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. - -# (Deprecated; Look at gameserverallocation.yaml instead) - -apiVersion: "stable.agones.dev/v1alpha1" -kind: FleetAllocation -metadata: - # generate a unique name - # will need to be created with `kubectl create` - generateName: simple-udp- -spec: - fleetName: simple-udp \ No newline at end of file diff --git a/examples/xonotic/fleetallocation.yaml b/examples/xonotic/fleetallocation.yaml deleted file mode 100644 index 6cee681fe6..0000000000 --- a/examples/xonotic/fleetallocation.yaml +++ /dev/null @@ -1,24 +0,0 @@ -# Copyright 2018 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. - -# (Deprecated; Look at gameserverallocation.yaml instead) - -apiVersion: "stable.agones.dev/v1alpha1" -kind: FleetAllocation -metadata: - # generate a unique name - # will need to be created with `kubectl create` - generateName: xonotic- -spec: - fleetName: xonotic diff --git a/install/helm/agones/scripts/delete_agones_resources.sh b/install/helm/agones/scripts/delete_agones_resources.sh index 46e33e8a95..aa55eb0d27 100755 --- a/install/helm/agones/scripts/delete_agones_resources.sh +++ b/install/helm/agones/scripts/delete_agones_resources.sh @@ -31,7 +31,6 @@ for ns in $namespaces; do kubectl -n $ns delete fleets --all kubectl -n $ns delete gameserversets --all kubectl -n $ns delete gameservers --all - kubectl -n $ns delete fleetallocations --all kubectl -n $ns delete gameserverallocationpolicies --all # Since we don't have the nifty kubectl wait yet, hack one in the meantime diff --git a/install/helm/agones/templates/crds/fleetallocation.yaml b/install/helm/agones/templates/crds/fleetallocation.yaml deleted file mode 100644 index 1410438dcd..0000000000 --- a/install/helm/agones/templates/crds/fleetallocation.yaml +++ /dev/null @@ -1,66 +0,0 @@ -# Copyright 2018 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. - -{{- if .Values.agones.crds.install }} - -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - name: fleetallocations.stable.agones.dev - labels: - component: crd - app: {{ template "agones.name" . }} - chart: {{ template "agones.chart" . }} - release: {{ .Release.Name }} - heritage: {{ .Release.Service }} -spec: - additionalPrinterColumns: - - JSONPath: .status.gameServer.status.state - name: State - type: string - - JSONPath: .status.gameServer.status.address - name: Address - type: string - - JSONPath: .status.gameServer.status.ports[0].port - name: Port - type: string - - JSONPath: .status.gameServer.status.nodeName - name: Node - type: string - - JSONPath: .metadata.creationTimestamp - name: Age - type: date - group: stable.agones.dev - version: v1alpha1 - scope: Namespaced - names: - kind: FleetAllocation - plural: fleetallocations - shortNames: - - fla - singular: fleetallocation - validation: - openAPIV3Schema: - properties: - spec: - required: - - fleetName - properties: - fleetName: - type: string - minLength: 1 - maxLength: 63 - pattern: "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$" - -{{- end }} diff --git a/install/helm/agones/templates/extensions.yaml b/install/helm/agones/templates/extensions.yaml index 19eba65dc5..1dfd212503 100644 --- a/install/helm/agones/templates/extensions.yaml +++ b/install/helm/agones/templates/extensions.yaml @@ -74,7 +74,6 @@ webhooks: - "fleets" - "gameservers" - "gameserversets" - - "fleetallocations" apiVersions: - "v1alpha1" operations: @@ -84,7 +83,6 @@ webhooks: resources: - "fleets" - "gameserversets" - - "fleetallocations" apiVersions: - "v1alpha1" operations: @@ -129,7 +127,6 @@ webhooks: resources: - "gameservers" - "fleets" - - "fleetallocations" apiVersions: - "v1alpha1" operations: diff --git a/install/helm/agones/templates/hooks/sa.yaml b/install/helm/agones/templates/hooks/sa.yaml index 8cbaa950c5..e5894a12b0 100644 --- a/install/helm/agones/templates/hooks/sa.yaml +++ b/install/helm/agones/templates/hooks/sa.yaml @@ -45,7 +45,7 @@ metadata: "helm.sh/hook-delete-policy": before-hook-creation rules: - apiGroups: ["stable.agones.dev", "multicluster.agones.dev", "autoscaling.agones.dev"] - resources: ["fleets", "fleetallocations", "fleetautoscalers", "gameservers", "gameserversets", "gameserverallocationpolicies"] + resources: ["fleets", "fleetautoscalers", "gameservers", "gameserversets", "gameserverallocationpolicies"] verbs: ["delete", "list" ] - apiGroups: [""] resources: ["pods"] diff --git a/install/helm/agones/templates/serviceaccounts/controller.yaml b/install/helm/agones/templates/serviceaccounts/controller.yaml index 6eb0c9e383..9cb10c12d3 100644 --- a/install/helm/agones/templates/serviceaccounts/controller.yaml +++ b/install/helm/agones/templates/serviceaccounts/controller.yaml @@ -56,7 +56,7 @@ rules: resources: ["gameservers"] verbs: ["patch"] - apiGroups: ["stable.agones.dev"] - resources: ["fleets", "fleetallocations"] + resources: ["fleets"] verbs: ["get", "list", "update", "watch"] - apiGroups: ["stable.agones.dev"] resources: ["fleets/status", "gameserversets/status"] @@ -70,8 +70,6 @@ rules: - apiGroups: ["autoscaling.agones.dev"] resources: ["fleetautoscalers/status"] verbs: ["update"] - - --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding diff --git a/install/yaml/install.yaml b/install/yaml/install.yaml index c60ac2d2b2..dcc14c7d9a 100644 --- a/install/yaml/install.yaml +++ b/install/yaml/install.yaml @@ -54,7 +54,7 @@ rules: resources: ["gameservers"] verbs: ["patch"] - apiGroups: ["stable.agones.dev"] - resources: ["fleets", "fleetallocations"] + resources: ["fleets"] verbs: ["get", "list", "update", "watch"] - apiGroups: ["stable.agones.dev"] resources: ["fleets/status", "gameserversets/status"] @@ -68,8 +68,6 @@ rules: - apiGroups: ["autoscaling.agones.dev"] resources: ["fleetautoscalers/status"] verbs: ["update"] - - --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding @@ -380,71 +378,6 @@ spec: # labelSelectorPath defines the JSONPath inside of a custom resource that corresponds to Scale.Status.Selector. labelSelectorPath: .status.labelSelector ---- -# Source: agones/templates/crds/fleetallocation.yaml -# Copyright 2018 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. - -apiVersion: apiextensions.k8s.io/v1beta1 -kind: CustomResourceDefinition -metadata: - name: fleetallocations.stable.agones.dev - labels: - component: crd - app: agones - chart: agones-0.12.0 - release: agones-manual - heritage: Tiller -spec: - additionalPrinterColumns: - - JSONPath: .status.gameServer.status.state - name: State - type: string - - JSONPath: .status.gameServer.status.address - name: Address - type: string - - JSONPath: .status.gameServer.status.ports[0].port - name: Port - type: string - - JSONPath: .status.gameServer.status.nodeName - name: Node - type: string - - JSONPath: .metadata.creationTimestamp - name: Age - type: date - group: stable.agones.dev - version: v1alpha1 - scope: Namespaced - names: - kind: FleetAllocation - plural: fleetallocations - shortNames: - - fla - singular: fleetallocation - validation: - openAPIV3Schema: - properties: - spec: - required: - - fleetName - properties: - fleetName: - type: string - minLength: 1 - maxLength: 63 - pattern: "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$" - --- # Source: agones/templates/crds/fleetautoscaler.yaml # Copyright 2018 Google LLC All Rights Reserved. @@ -1494,7 +1427,6 @@ webhooks: - "fleets" - "gameservers" - "gameserversets" - - "fleetallocations" apiVersions: - "v1alpha1" operations: @@ -1504,7 +1436,6 @@ webhooks: resources: - "fleets" - "gameserversets" - - "fleetallocations" apiVersions: - "v1alpha1" operations: @@ -1545,7 +1476,6 @@ webhooks: resources: - "gameservers" - "fleets" - - "fleetallocations" apiVersions: - "v1alpha1" operations: diff --git a/pkg/apis/stable/v1alpha1/fleetallocation.go b/pkg/apis/stable/v1alpha1/fleetallocation.go deleted file mode 100644 index 905600c49d..0000000000 --- a/pkg/apis/stable/v1alpha1/fleetallocation.go +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright 2018 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. - -package v1alpha1 - -import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - -// +genclient -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -// FleetAllocation is the data structure for allocating against a Fleet -// Deprecated: Please use GameServerAllocation instead. -type FleetAllocation struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata,omitempty"` - - Spec FleetAllocationSpec `json:"spec"` - Status FleetAllocationStatus `json:"status,omitempty"` -} - -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -// FleetAllocationList is a list of Fleet Allocation resources -type FleetAllocationList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata,omitempty"` - - Items []FleetAllocation `json:"items"` -} - -// FleetAllocationSpec is the spec for a Fleet -// Allocation -type FleetAllocationSpec struct { - FleetName string `json:"fleetName"` - MetaPatch MetaPatch `json:"metadata,omitempty"` -} - -// MetaPatch is the metadata used to patch the GameServer metadata on allocation -type MetaPatch struct { - Labels map[string]string `json:"labels,omitempty"` - Annotations map[string]string `json:"annotations,omitempty"` -} - -// FleetAllocationStatus will contain the -// `GameServer` that has been allocated from -// a Fleet -type FleetAllocationStatus struct { - GameServer *GameServer `json:"gameServer,omitempty"` -} - -// ValidateUpdate validates when an update occurs -func (fa *FleetAllocation) ValidateUpdate(new *FleetAllocation) ([]metav1.StatusCause, bool) { - var causes []metav1.StatusCause - - if fa.Spec.FleetName != new.Spec.FleetName { - causes = append(causes, metav1.StatusCause{ - Type: metav1.CauseTypeFieldValueInvalid, - Field: "fleetName", - Message: "fleetName cannot be updated", - }) - } - - return causes, len(causes) == 0 -} diff --git a/pkg/apis/stable/v1alpha1/fleetallocation_test.go b/pkg/apis/stable/v1alpha1/fleetallocation_test.go deleted file mode 100644 index 5b31cd3e10..0000000000 --- a/pkg/apis/stable/v1alpha1/fleetallocation_test.go +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2018 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. - -package v1alpha1 - -import ( - "testing" - - "github.com/stretchr/testify/assert" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -func TestFleetAllocationValidateupdate(t *testing.T) { - fa := &FleetAllocation{ - ObjectMeta: metav1.ObjectMeta{Name: "test"}, - Spec: FleetAllocationSpec{ - FleetName: "testing", - }, - } - - causes, valid := fa.ValidateUpdate(fa.DeepCopy()) - assert.True(t, valid) - assert.Len(t, causes, 0) - - faCopy := fa.DeepCopy() - faCopy.Spec.FleetName = "notthesame" - causes, valid = fa.ValidateUpdate(faCopy) - - assert.False(t, valid) - assert.Len(t, causes, 1) - assert.Equal(t, "fleetName", causes[0].Field) -} diff --git a/pkg/apis/stable/v1alpha1/register.go b/pkg/apis/stable/v1alpha1/register.go index 6d181e1fda..9f57136ced 100644 --- a/pkg/apis/stable/v1alpha1/register.go +++ b/pkg/apis/stable/v1alpha1/register.go @@ -57,8 +57,6 @@ func addKnownTypes(scheme *k8sruntime.Scheme) error { &GameServerSetList{}, &Fleet{}, &FleetList{}, - &FleetAllocation{}, - &FleetAllocationList{}, ) metav1.AddToGroupVersion(scheme, SchemeGroupVersion) return nil diff --git a/pkg/apis/stable/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/stable/v1alpha1/zz_generated.deepcopy.go index a4bc18c98b..f2983559dc 100644 --- a/pkg/apis/stable/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/stable/v1alpha1/zz_generated.deepcopy.go @@ -52,109 +52,6 @@ func (in *Fleet) DeepCopyObject() runtime.Object { return nil } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *FleetAllocation) DeepCopyInto(out *FleetAllocation) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) - in.Status.DeepCopyInto(&out.Status) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FleetAllocation. -func (in *FleetAllocation) DeepCopy() *FleetAllocation { - if in == nil { - return nil - } - out := new(FleetAllocation) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *FleetAllocation) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *FleetAllocationList) DeepCopyInto(out *FleetAllocationList) { - *out = *in - out.TypeMeta = in.TypeMeta - out.ListMeta = in.ListMeta - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]FleetAllocation, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FleetAllocationList. -func (in *FleetAllocationList) DeepCopy() *FleetAllocationList { - if in == nil { - return nil - } - out := new(FleetAllocationList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *FleetAllocationList) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *FleetAllocationSpec) DeepCopyInto(out *FleetAllocationSpec) { - *out = *in - in.MetaPatch.DeepCopyInto(&out.MetaPatch) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FleetAllocationSpec. -func (in *FleetAllocationSpec) DeepCopy() *FleetAllocationSpec { - if in == nil { - return nil - } - out := new(FleetAllocationSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *FleetAllocationStatus) DeepCopyInto(out *FleetAllocationStatus) { - *out = *in - if in.GameServer != nil { - in, out := &in.GameServer, &out.GameServer - if *in == nil { - *out = nil - } else { - *out = new(GameServer) - (*in).DeepCopyInto(*out) - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FleetAllocationStatus. -func (in *FleetAllocationStatus) DeepCopy() *FleetAllocationStatus { - if in == nil { - return nil - } - out := new(FleetAllocationStatus) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *FleetList) DeepCopyInto(out *FleetList) { *out = *in @@ -486,33 +383,3 @@ func (in *Health) DeepCopy() *Health { in.DeepCopyInto(out) return out } - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *MetaPatch) DeepCopyInto(out *MetaPatch) { - *out = *in - if in.Labels != nil { - in, out := &in.Labels, &out.Labels - *out = make(map[string]string, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } - if in.Annotations != nil { - in, out := &in.Annotations, &out.Annotations - *out = make(map[string]string, len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MetaPatch. -func (in *MetaPatch) DeepCopy() *MetaPatch { - if in == nil { - return nil - } - out := new(MetaPatch) - in.DeepCopyInto(out) - return out -} diff --git a/pkg/client/clientset/versioned/typed/stable/v1alpha1/fake/fake_fleetallocation.go b/pkg/client/clientset/versioned/typed/stable/v1alpha1/fake/fake_fleetallocation.go deleted file mode 100644 index 60b14af9b1..0000000000 --- a/pkg/client/clientset/versioned/typed/stable/v1alpha1/fake/fake_fleetallocation.go +++ /dev/null @@ -1,140 +0,0 @@ -// Copyright 2019 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 client-gen. DO NOT EDIT. - -package fake - -import ( - v1alpha1 "agones.dev/agones/pkg/apis/stable/v1alpha1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - labels "k8s.io/apimachinery/pkg/labels" - schema "k8s.io/apimachinery/pkg/runtime/schema" - types "k8s.io/apimachinery/pkg/types" - watch "k8s.io/apimachinery/pkg/watch" - testing "k8s.io/client-go/testing" -) - -// FakeFleetAllocations implements FleetAllocationInterface -type FakeFleetAllocations struct { - Fake *FakeStableV1alpha1 - ns string -} - -var fleetallocationsResource = schema.GroupVersionResource{Group: "stable.agones.dev", Version: "v1alpha1", Resource: "fleetallocations"} - -var fleetallocationsKind = schema.GroupVersionKind{Group: "stable.agones.dev", Version: "v1alpha1", Kind: "FleetAllocation"} - -// Get takes name of the fleetAllocation, and returns the corresponding fleetAllocation object, and an error if there is any. -func (c *FakeFleetAllocations) Get(name string, options v1.GetOptions) (result *v1alpha1.FleetAllocation, err error) { - obj, err := c.Fake. - Invokes(testing.NewGetAction(fleetallocationsResource, c.ns, name), &v1alpha1.FleetAllocation{}) - - if obj == nil { - return nil, err - } - return obj.(*v1alpha1.FleetAllocation), err -} - -// List takes label and field selectors, and returns the list of FleetAllocations that match those selectors. -func (c *FakeFleetAllocations) List(opts v1.ListOptions) (result *v1alpha1.FleetAllocationList, err error) { - obj, err := c.Fake. - Invokes(testing.NewListAction(fleetallocationsResource, fleetallocationsKind, c.ns, opts), &v1alpha1.FleetAllocationList{}) - - if obj == nil { - return nil, err - } - - label, _, _ := testing.ExtractFromListOptions(opts) - if label == nil { - label = labels.Everything() - } - list := &v1alpha1.FleetAllocationList{ListMeta: obj.(*v1alpha1.FleetAllocationList).ListMeta} - for _, item := range obj.(*v1alpha1.FleetAllocationList).Items { - if label.Matches(labels.Set(item.Labels)) { - list.Items = append(list.Items, item) - } - } - return list, err -} - -// Watch returns a watch.Interface that watches the requested fleetAllocations. -func (c *FakeFleetAllocations) Watch(opts v1.ListOptions) (watch.Interface, error) { - return c.Fake. - InvokesWatch(testing.NewWatchAction(fleetallocationsResource, c.ns, opts)) - -} - -// Create takes the representation of a fleetAllocation and creates it. Returns the server's representation of the fleetAllocation, and an error, if there is any. -func (c *FakeFleetAllocations) Create(fleetAllocation *v1alpha1.FleetAllocation) (result *v1alpha1.FleetAllocation, err error) { - obj, err := c.Fake. - Invokes(testing.NewCreateAction(fleetallocationsResource, c.ns, fleetAllocation), &v1alpha1.FleetAllocation{}) - - if obj == nil { - return nil, err - } - return obj.(*v1alpha1.FleetAllocation), err -} - -// Update takes the representation of a fleetAllocation and updates it. Returns the server's representation of the fleetAllocation, and an error, if there is any. -func (c *FakeFleetAllocations) Update(fleetAllocation *v1alpha1.FleetAllocation) (result *v1alpha1.FleetAllocation, err error) { - obj, err := c.Fake. - Invokes(testing.NewUpdateAction(fleetallocationsResource, c.ns, fleetAllocation), &v1alpha1.FleetAllocation{}) - - if obj == nil { - return nil, err - } - return obj.(*v1alpha1.FleetAllocation), err -} - -// UpdateStatus was generated because the type contains a Status member. -// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). -func (c *FakeFleetAllocations) UpdateStatus(fleetAllocation *v1alpha1.FleetAllocation) (*v1alpha1.FleetAllocation, error) { - obj, err := c.Fake. - Invokes(testing.NewUpdateSubresourceAction(fleetallocationsResource, "status", c.ns, fleetAllocation), &v1alpha1.FleetAllocation{}) - - if obj == nil { - return nil, err - } - return obj.(*v1alpha1.FleetAllocation), err -} - -// Delete takes name of the fleetAllocation and deletes it. Returns an error if one occurs. -func (c *FakeFleetAllocations) Delete(name string, options *v1.DeleteOptions) error { - _, err := c.Fake. - Invokes(testing.NewDeleteAction(fleetallocationsResource, c.ns, name), &v1alpha1.FleetAllocation{}) - - return err -} - -// DeleteCollection deletes a collection of objects. -func (c *FakeFleetAllocations) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { - action := testing.NewDeleteCollectionAction(fleetallocationsResource, c.ns, listOptions) - - _, err := c.Fake.Invokes(action, &v1alpha1.FleetAllocationList{}) - return err -} - -// Patch applies the patch and returns the patched fleetAllocation. -func (c *FakeFleetAllocations) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.FleetAllocation, err error) { - obj, err := c.Fake. - Invokes(testing.NewPatchSubresourceAction(fleetallocationsResource, c.ns, name, data, subresources...), &v1alpha1.FleetAllocation{}) - - if obj == nil { - return nil, err - } - return obj.(*v1alpha1.FleetAllocation), err -} diff --git a/pkg/client/clientset/versioned/typed/stable/v1alpha1/fake/fake_stable_client.go b/pkg/client/clientset/versioned/typed/stable/v1alpha1/fake/fake_stable_client.go index 07b7ad60d7..67045fa90e 100644 --- a/pkg/client/clientset/versioned/typed/stable/v1alpha1/fake/fake_stable_client.go +++ b/pkg/client/clientset/versioned/typed/stable/v1alpha1/fake/fake_stable_client.go @@ -32,10 +32,6 @@ func (c *FakeStableV1alpha1) Fleets(namespace string) v1alpha1.FleetInterface { return &FakeFleets{c, namespace} } -func (c *FakeStableV1alpha1) FleetAllocations(namespace string) v1alpha1.FleetAllocationInterface { - return &FakeFleetAllocations{c, namespace} -} - func (c *FakeStableV1alpha1) GameServers(namespace string) v1alpha1.GameServerInterface { return &FakeGameServers{c, namespace} } diff --git a/pkg/client/clientset/versioned/typed/stable/v1alpha1/fleetallocation.go b/pkg/client/clientset/versioned/typed/stable/v1alpha1/fleetallocation.go deleted file mode 100644 index d922c55db5..0000000000 --- a/pkg/client/clientset/versioned/typed/stable/v1alpha1/fleetallocation.go +++ /dev/null @@ -1,174 +0,0 @@ -// Copyright 2019 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 client-gen. DO NOT EDIT. - -package v1alpha1 - -import ( - v1alpha1 "agones.dev/agones/pkg/apis/stable/v1alpha1" - scheme "agones.dev/agones/pkg/client/clientset/versioned/scheme" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - types "k8s.io/apimachinery/pkg/types" - watch "k8s.io/apimachinery/pkg/watch" - rest "k8s.io/client-go/rest" -) - -// FleetAllocationsGetter has a method to return a FleetAllocationInterface. -// A group's client should implement this interface. -type FleetAllocationsGetter interface { - FleetAllocations(namespace string) FleetAllocationInterface -} - -// FleetAllocationInterface has methods to work with FleetAllocation resources. -type FleetAllocationInterface interface { - Create(*v1alpha1.FleetAllocation) (*v1alpha1.FleetAllocation, error) - Update(*v1alpha1.FleetAllocation) (*v1alpha1.FleetAllocation, error) - UpdateStatus(*v1alpha1.FleetAllocation) (*v1alpha1.FleetAllocation, error) - Delete(name string, options *v1.DeleteOptions) error - DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error - Get(name string, options v1.GetOptions) (*v1alpha1.FleetAllocation, error) - List(opts v1.ListOptions) (*v1alpha1.FleetAllocationList, error) - Watch(opts v1.ListOptions) (watch.Interface, error) - Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.FleetAllocation, err error) - FleetAllocationExpansion -} - -// fleetAllocations implements FleetAllocationInterface -type fleetAllocations struct { - client rest.Interface - ns string -} - -// newFleetAllocations returns a FleetAllocations -func newFleetAllocations(c *StableV1alpha1Client, namespace string) *fleetAllocations { - return &fleetAllocations{ - client: c.RESTClient(), - ns: namespace, - } -} - -// Get takes name of the fleetAllocation, and returns the corresponding fleetAllocation object, and an error if there is any. -func (c *fleetAllocations) Get(name string, options v1.GetOptions) (result *v1alpha1.FleetAllocation, err error) { - result = &v1alpha1.FleetAllocation{} - err = c.client.Get(). - Namespace(c.ns). - Resource("fleetallocations"). - Name(name). - VersionedParams(&options, scheme.ParameterCodec). - Do(). - Into(result) - return -} - -// List takes label and field selectors, and returns the list of FleetAllocations that match those selectors. -func (c *fleetAllocations) List(opts v1.ListOptions) (result *v1alpha1.FleetAllocationList, err error) { - result = &v1alpha1.FleetAllocationList{} - err = c.client.Get(). - Namespace(c.ns). - Resource("fleetallocations"). - VersionedParams(&opts, scheme.ParameterCodec). - Do(). - Into(result) - return -} - -// Watch returns a watch.Interface that watches the requested fleetAllocations. -func (c *fleetAllocations) Watch(opts v1.ListOptions) (watch.Interface, error) { - opts.Watch = true - return c.client.Get(). - Namespace(c.ns). - Resource("fleetallocations"). - VersionedParams(&opts, scheme.ParameterCodec). - Watch() -} - -// Create takes the representation of a fleetAllocation and creates it. Returns the server's representation of the fleetAllocation, and an error, if there is any. -func (c *fleetAllocations) Create(fleetAllocation *v1alpha1.FleetAllocation) (result *v1alpha1.FleetAllocation, err error) { - result = &v1alpha1.FleetAllocation{} - err = c.client.Post(). - Namespace(c.ns). - Resource("fleetallocations"). - Body(fleetAllocation). - Do(). - Into(result) - return -} - -// Update takes the representation of a fleetAllocation and updates it. Returns the server's representation of the fleetAllocation, and an error, if there is any. -func (c *fleetAllocations) Update(fleetAllocation *v1alpha1.FleetAllocation) (result *v1alpha1.FleetAllocation, err error) { - result = &v1alpha1.FleetAllocation{} - err = c.client.Put(). - Namespace(c.ns). - Resource("fleetallocations"). - Name(fleetAllocation.Name). - Body(fleetAllocation). - Do(). - Into(result) - return -} - -// UpdateStatus was generated because the type contains a Status member. -// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). - -func (c *fleetAllocations) UpdateStatus(fleetAllocation *v1alpha1.FleetAllocation) (result *v1alpha1.FleetAllocation, err error) { - result = &v1alpha1.FleetAllocation{} - err = c.client.Put(). - Namespace(c.ns). - Resource("fleetallocations"). - Name(fleetAllocation.Name). - SubResource("status"). - Body(fleetAllocation). - Do(). - Into(result) - return -} - -// Delete takes name of the fleetAllocation and deletes it. Returns an error if one occurs. -func (c *fleetAllocations) Delete(name string, options *v1.DeleteOptions) error { - return c.client.Delete(). - Namespace(c.ns). - Resource("fleetallocations"). - Name(name). - Body(options). - Do(). - Error() -} - -// DeleteCollection deletes a collection of objects. -func (c *fleetAllocations) DeleteCollection(options *v1.DeleteOptions, listOptions v1.ListOptions) error { - return c.client.Delete(). - Namespace(c.ns). - Resource("fleetallocations"). - VersionedParams(&listOptions, scheme.ParameterCodec). - Body(options). - Do(). - Error() -} - -// Patch applies the patch and returns the patched fleetAllocation. -func (c *fleetAllocations) Patch(name string, pt types.PatchType, data []byte, subresources ...string) (result *v1alpha1.FleetAllocation, err error) { - result = &v1alpha1.FleetAllocation{} - err = c.client.Patch(pt). - Namespace(c.ns). - Resource("fleetallocations"). - SubResource(subresources...). - Name(name). - Body(data). - Do(). - Into(result) - return -} diff --git a/pkg/client/clientset/versioned/typed/stable/v1alpha1/generated_expansion.go b/pkg/client/clientset/versioned/typed/stable/v1alpha1/generated_expansion.go index c4feea7a1f..b67ccc001c 100644 --- a/pkg/client/clientset/versioned/typed/stable/v1alpha1/generated_expansion.go +++ b/pkg/client/clientset/versioned/typed/stable/v1alpha1/generated_expansion.go @@ -20,8 +20,6 @@ package v1alpha1 type FleetExpansion interface{} -type FleetAllocationExpansion interface{} - type GameServerExpansion interface{} type GameServerSetExpansion interface{} diff --git a/pkg/client/clientset/versioned/typed/stable/v1alpha1/stable_client.go b/pkg/client/clientset/versioned/typed/stable/v1alpha1/stable_client.go index 73333d3b1d..c4c2f97276 100644 --- a/pkg/client/clientset/versioned/typed/stable/v1alpha1/stable_client.go +++ b/pkg/client/clientset/versioned/typed/stable/v1alpha1/stable_client.go @@ -28,7 +28,6 @@ import ( type StableV1alpha1Interface interface { RESTClient() rest.Interface FleetsGetter - FleetAllocationsGetter GameServersGetter GameServerSetsGetter } @@ -42,10 +41,6 @@ func (c *StableV1alpha1Client) Fleets(namespace string) FleetInterface { return newFleets(c, namespace) } -func (c *StableV1alpha1Client) FleetAllocations(namespace string) FleetAllocationInterface { - return newFleetAllocations(c, namespace) -} - func (c *StableV1alpha1Client) GameServers(namespace string) GameServerInterface { return newGameServers(c, namespace) } diff --git a/pkg/client/informers/externalversions/generic.go b/pkg/client/informers/externalversions/generic.go index f02cbf495c..ba8e9d9fe6 100644 --- a/pkg/client/informers/externalversions/generic.go +++ b/pkg/client/informers/externalversions/generic.go @@ -65,8 +65,6 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource // Group=stable.agones.dev, Version=v1alpha1 case stable_v1alpha1.SchemeGroupVersion.WithResource("fleets"): return &genericInformer{resource: resource.GroupResource(), informer: f.Stable().V1alpha1().Fleets().Informer()}, nil - case stable_v1alpha1.SchemeGroupVersion.WithResource("fleetallocations"): - return &genericInformer{resource: resource.GroupResource(), informer: f.Stable().V1alpha1().FleetAllocations().Informer()}, nil case stable_v1alpha1.SchemeGroupVersion.WithResource("gameservers"): return &genericInformer{resource: resource.GroupResource(), informer: f.Stable().V1alpha1().GameServers().Informer()}, nil case stable_v1alpha1.SchemeGroupVersion.WithResource("gameserversets"): diff --git a/pkg/client/informers/externalversions/stable/v1alpha1/fleetallocation.go b/pkg/client/informers/externalversions/stable/v1alpha1/fleetallocation.go deleted file mode 100644 index 9a8eb8bcbb..0000000000 --- a/pkg/client/informers/externalversions/stable/v1alpha1/fleetallocation.go +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright 2019 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 informer-gen. DO NOT EDIT. - -package v1alpha1 - -import ( - time "time" - - stable_v1alpha1 "agones.dev/agones/pkg/apis/stable/v1alpha1" - versioned "agones.dev/agones/pkg/client/clientset/versioned" - internalinterfaces "agones.dev/agones/pkg/client/informers/externalversions/internalinterfaces" - v1alpha1 "agones.dev/agones/pkg/client/listers/stable/v1alpha1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - runtime "k8s.io/apimachinery/pkg/runtime" - watch "k8s.io/apimachinery/pkg/watch" - cache "k8s.io/client-go/tools/cache" -) - -// FleetAllocationInformer provides access to a shared informer and lister for -// FleetAllocations. -type FleetAllocationInformer interface { - Informer() cache.SharedIndexInformer - Lister() v1alpha1.FleetAllocationLister -} - -type fleetAllocationInformer struct { - factory internalinterfaces.SharedInformerFactory - tweakListOptions internalinterfaces.TweakListOptionsFunc - namespace string -} - -// NewFleetAllocationInformer constructs a new informer for FleetAllocation type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewFleetAllocationInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { - return NewFilteredFleetAllocationInformer(client, namespace, resyncPeriod, indexers, nil) -} - -// NewFilteredFleetAllocationInformer constructs a new informer for FleetAllocation type. -// Always prefer using an informer factory to get a shared informer instead of getting an independent -// one. This reduces memory footprint and number of connections to the server. -func NewFilteredFleetAllocationInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { - return cache.NewSharedIndexInformer( - &cache.ListWatch{ - ListFunc: func(options v1.ListOptions) (runtime.Object, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.StableV1alpha1().FleetAllocations(namespace).List(options) - }, - WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { - if tweakListOptions != nil { - tweakListOptions(&options) - } - return client.StableV1alpha1().FleetAllocations(namespace).Watch(options) - }, - }, - &stable_v1alpha1.FleetAllocation{}, - resyncPeriod, - indexers, - ) -} - -func (f *fleetAllocationInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - return NewFilteredFleetAllocationInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) -} - -func (f *fleetAllocationInformer) Informer() cache.SharedIndexInformer { - return f.factory.InformerFor(&stable_v1alpha1.FleetAllocation{}, f.defaultInformer) -} - -func (f *fleetAllocationInformer) Lister() v1alpha1.FleetAllocationLister { - return v1alpha1.NewFleetAllocationLister(f.Informer().GetIndexer()) -} diff --git a/pkg/client/informers/externalversions/stable/v1alpha1/interface.go b/pkg/client/informers/externalversions/stable/v1alpha1/interface.go index a0a1e84f06..05fa8c5323 100644 --- a/pkg/client/informers/externalversions/stable/v1alpha1/interface.go +++ b/pkg/client/informers/externalversions/stable/v1alpha1/interface.go @@ -26,8 +26,6 @@ import ( type Interface interface { // Fleets returns a FleetInformer. Fleets() FleetInformer - // FleetAllocations returns a FleetAllocationInformer. - FleetAllocations() FleetAllocationInformer // GameServers returns a GameServerInformer. GameServers() GameServerInformer // GameServerSets returns a GameServerSetInformer. @@ -50,11 +48,6 @@ func (v *version) Fleets() FleetInformer { return &fleetInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} } -// FleetAllocations returns a FleetAllocationInformer. -func (v *version) FleetAllocations() FleetAllocationInformer { - return &fleetAllocationInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} -} - // GameServers returns a GameServerInformer. func (v *version) GameServers() GameServerInformer { return &gameServerInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} diff --git a/pkg/client/listers/stable/v1alpha1/expansion_generated.go b/pkg/client/listers/stable/v1alpha1/expansion_generated.go index fb2a0ba7b2..1405aebfb9 100644 --- a/pkg/client/listers/stable/v1alpha1/expansion_generated.go +++ b/pkg/client/listers/stable/v1alpha1/expansion_generated.go @@ -26,14 +26,6 @@ type FleetListerExpansion interface{} // FleetNamespaceLister. type FleetNamespaceListerExpansion interface{} -// FleetAllocationListerExpansion allows custom methods to be added to -// FleetAllocationLister. -type FleetAllocationListerExpansion interface{} - -// FleetAllocationNamespaceListerExpansion allows custom methods to be added to -// FleetAllocationNamespaceLister. -type FleetAllocationNamespaceListerExpansion interface{} - // GameServerListerExpansion allows custom methods to be added to // GameServerLister. type GameServerListerExpansion interface{} diff --git a/pkg/client/listers/stable/v1alpha1/fleetallocation.go b/pkg/client/listers/stable/v1alpha1/fleetallocation.go deleted file mode 100644 index ecc4d02e63..0000000000 --- a/pkg/client/listers/stable/v1alpha1/fleetallocation.go +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright 2019 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 lister-gen. DO NOT EDIT. - -package v1alpha1 - -import ( - v1alpha1 "agones.dev/agones/pkg/apis/stable/v1alpha1" - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/tools/cache" -) - -// FleetAllocationLister helps list FleetAllocations. -type FleetAllocationLister interface { - // List lists all FleetAllocations in the indexer. - List(selector labels.Selector) (ret []*v1alpha1.FleetAllocation, err error) - // FleetAllocations returns an object that can list and get FleetAllocations. - FleetAllocations(namespace string) FleetAllocationNamespaceLister - FleetAllocationListerExpansion -} - -// fleetAllocationLister implements the FleetAllocationLister interface. -type fleetAllocationLister struct { - indexer cache.Indexer -} - -// NewFleetAllocationLister returns a new FleetAllocationLister. -func NewFleetAllocationLister(indexer cache.Indexer) FleetAllocationLister { - return &fleetAllocationLister{indexer: indexer} -} - -// List lists all FleetAllocations in the indexer. -func (s *fleetAllocationLister) List(selector labels.Selector) (ret []*v1alpha1.FleetAllocation, err error) { - err = cache.ListAll(s.indexer, selector, func(m interface{}) { - ret = append(ret, m.(*v1alpha1.FleetAllocation)) - }) - return ret, err -} - -// FleetAllocations returns an object that can list and get FleetAllocations. -func (s *fleetAllocationLister) FleetAllocations(namespace string) FleetAllocationNamespaceLister { - return fleetAllocationNamespaceLister{indexer: s.indexer, namespace: namespace} -} - -// FleetAllocationNamespaceLister helps list and get FleetAllocations. -type FleetAllocationNamespaceLister interface { - // List lists all FleetAllocations in the indexer for a given namespace. - List(selector labels.Selector) (ret []*v1alpha1.FleetAllocation, err error) - // Get retrieves the FleetAllocation from the indexer for a given namespace and name. - Get(name string) (*v1alpha1.FleetAllocation, error) - FleetAllocationNamespaceListerExpansion -} - -// fleetAllocationNamespaceLister implements the FleetAllocationNamespaceLister -// interface. -type fleetAllocationNamespaceLister struct { - indexer cache.Indexer - namespace string -} - -// List lists all FleetAllocations in the indexer for a given namespace. -func (s fleetAllocationNamespaceLister) List(selector labels.Selector) (ret []*v1alpha1.FleetAllocation, err error) { - err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { - ret = append(ret, m.(*v1alpha1.FleetAllocation)) - }) - return ret, err -} - -// Get retrieves the FleetAllocation from the indexer for a given namespace and name. -func (s fleetAllocationNamespaceLister) Get(name string) (*v1alpha1.FleetAllocation, error) { - obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) - if err != nil { - return nil, err - } - if !exists { - return nil, errors.NewNotFound(v1alpha1.Resource("fleetallocation"), name) - } - return obj.(*v1alpha1.FleetAllocation), nil -} diff --git a/pkg/fleetallocation/controller.go b/pkg/fleetallocation/controller.go deleted file mode 100644 index efd803711b..0000000000 --- a/pkg/fleetallocation/controller.go +++ /dev/null @@ -1,324 +0,0 @@ -// Copyright 2018 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. - -package fleetallocation - -import ( - "encoding/json" - "fmt" - "sync" - - "agones.dev/agones/pkg/apis" - "agones.dev/agones/pkg/apis/stable" - "agones.dev/agones/pkg/apis/stable/v1alpha1" - "agones.dev/agones/pkg/client/clientset/versioned" - getterv1alpha1 "agones.dev/agones/pkg/client/clientset/versioned/typed/stable/v1alpha1" - "agones.dev/agones/pkg/client/informers/externalversions" - listerv1alpha1 "agones.dev/agones/pkg/client/listers/stable/v1alpha1" - "agones.dev/agones/pkg/fleets" - "agones.dev/agones/pkg/util/crd" - "agones.dev/agones/pkg/util/runtime" - "agones.dev/agones/pkg/util/webhooks" - "github.com/mattbaird/jsonpatch" - "github.com/pkg/errors" - "github.com/sirupsen/logrus" - admv1beta1 "k8s.io/api/admission/v1beta1" - corev1 "k8s.io/api/core/v1" - extclientset "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" - "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1" - k8serrors "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/kubernetes" - "k8s.io/client-go/kubernetes/scheme" - typedcorev1 "k8s.io/client-go/kubernetes/typed/core/v1" - "k8s.io/client-go/tools/cache" - "k8s.io/client-go/tools/record" -) - -var ( - // ErrNoGameServerReady is returned when there are no Ready GameServers - // available - ErrNoGameServerReady = errors.New("Could not find a Ready GameServer") -) - -// Controller is a the FleetAllocation controller -type Controller struct { - logger *logrus.Entry - crdGetter v1beta1.CustomResourceDefinitionInterface - gameServerSynced cache.InformerSynced - gameServerGetter getterv1alpha1.GameServersGetter - gameServerLister listerv1alpha1.GameServerLister - gameServerSetLister listerv1alpha1.GameServerSetLister - fleetLister listerv1alpha1.FleetLister - fleetAllocationGetter getterv1alpha1.FleetAllocationsGetter - fleetAllocationLister listerv1alpha1.FleetAllocationLister - stop <-chan struct{} - allocationMutex *sync.Mutex - recorder record.EventRecorder -} - -// NewController returns a controller for a FleetAllocation -func NewController( - wh *webhooks.WebHook, - allocationMutex *sync.Mutex, - kubeClient kubernetes.Interface, - extClient extclientset.Interface, - agonesClient versioned.Interface, - agonesInformerFactory externalversions.SharedInformerFactory) *Controller { - - agonesInformer := agonesInformerFactory.Stable().V1alpha1() - c := &Controller{ - crdGetter: extClient.ApiextensionsV1beta1().CustomResourceDefinitions(), - gameServerSynced: agonesInformer.GameServers().Informer().HasSynced, - gameServerGetter: agonesClient.StableV1alpha1(), - gameServerLister: agonesInformer.GameServers().Lister(), - gameServerSetLister: agonesInformer.GameServerSets().Lister(), - fleetLister: agonesInformer.Fleets().Lister(), - fleetAllocationGetter: agonesClient.StableV1alpha1(), - fleetAllocationLister: agonesInformer.FleetAllocations().Lister(), - allocationMutex: allocationMutex, - } - c.logger = runtime.NewLoggerWithType(c) - - eventBroadcaster := record.NewBroadcaster() - eventBroadcaster.StartLogging(c.logger.Infof) - eventBroadcaster.StartRecordingToSink(&typedcorev1.EventSinkImpl{Interface: kubeClient.CoreV1().Events("")}) - c.recorder = eventBroadcaster.NewRecorder(scheme.Scheme, corev1.EventSource{Component: "fleetallocation-controller"}) - - kind := v1alpha1.Kind("FleetAllocation") - wh.AddHandler("/mutate", kind, admv1beta1.Create, c.creationMutationHandler) - wh.AddHandler("/validate", kind, admv1beta1.Create, c.creationValidationHandler) - wh.AddHandler("/validate", kind, admv1beta1.Update, c.mutationValidationHandler) - - return c -} - -// Run runs this controller. This controller doesn't (currently) -// have a worker/queue, and as such, does not block. -func (c *Controller) Run(workers int, stop <-chan struct{}) error { - err := crd.WaitForEstablishedCRD(c.crdGetter, "fleetallocations."+stable.GroupName, c.logger) - if err != nil { - return err - } - - c.stop = stop - return nil -} - -// creationMutationHandler will intercept when a FleetAllocation is created, and allocate it a GameServer -// assuming that one is available. If not, it will reject the AdmissionReview. -func (c *Controller) creationMutationHandler(review admv1beta1.AdmissionReview) (admv1beta1.AdmissionReview, error) { - c.logger.WithField("review", review).Info("creationMutationHandler") - obj := review.Request.Object - fa := &v1alpha1.FleetAllocation{} - - err := json.Unmarshal(obj.Raw, fa) - if err != nil { - return review, errors.Wrapf(err, "error unmarshalling original FleetAllocation json: %s", obj.Raw) - } - - // When being called from the API the fa.ObjectMeta.Namespace isn't populated - // (whereas it is from kubectl). So make sure to pull the namespace from the review - fleet, err := c.fleetLister.Fleets(review.Request.Namespace).Get(fa.Spec.FleetName) - if err != nil { - if k8serrors.IsNotFound(err) { - logrus.WithError(err).WithField("fleetName", fa.Name). - WithField("namespace", review.Request.Namespace). - Warn("Could not find fleet for allocation. Skipping.") - return review, nil - } - return review, errors.Wrapf(err, "error retrieving fleet %s", fa.Name) - } - - gs, err := c.allocate(fleet, &fa.Spec.MetaPatch) - if err != nil { - review.Response.Allowed = false - review.Response.Result = &metav1.Status{ - Status: metav1.StatusFailure, - Reason: metav1.StatusReasonNotFound, - Details: &metav1.StatusDetails{ - Name: review.Request.Name, - Group: review.Request.Kind.Group, - Kind: "GameServer", - }, - } - - return review, nil - } - - // When a GameServer is deleted, the FleetAllocation should go with it - ref := metav1.NewControllerRef(gs, v1alpha1.SchemeGroupVersion.WithKind("GameServer")) - fa.ObjectMeta.OwnerReferences = append(fa.ObjectMeta.OwnerReferences, *ref) - - fa.Status = v1alpha1.FleetAllocationStatus{GameServer: gs} - - newFA, err := json.Marshal(fa) - if err != nil { - return review, errors.Wrapf(err, "error marshalling FleetAllocation %s to json", fa.ObjectMeta.Name) - } - - patch, err := jsonpatch.CreatePatch(obj.Raw, newFA) - if err != nil { - return review, errors.Wrapf(err, "error creating patch for FleetAllocation %s", fa.ObjectMeta.Name) - } - - json, err := json.Marshal(patch) - if err != nil { - return review, errors.Wrapf(err, "error creating json for patch for FleetAllocation %s", gs.ObjectMeta.Name) - } - - c.logger.WithField("fa", fa.ObjectMeta.Name).WithField("patch", string(json)).Infof("patch created!") - - pt := admv1beta1.PatchTypeJSONPatch - review.Response.PatchType = &pt - review.Response.Patch = json - - return review, nil -} - -// creationValidationHandler intercepts the creation of a FleetAllocation, and if there is -// no Status > GameServer set, then we will assume that the Spec > fleetName is invalid -func (c *Controller) creationValidationHandler(review admv1beta1.AdmissionReview) (admv1beta1.AdmissionReview, error) { - c.logger.WithField("review", review).Info("creationValidationHandler") - obj := review.Request.Object - fa := &v1alpha1.FleetAllocation{} - if err := json.Unmarshal(obj.Raw, fa); err != nil { - return review, errors.Wrapf(err, "error unmarshalling original FleetAllocation json: %s", obj.Raw) - } - - // If there is no GameServer, we are assuming that is - // because the fleetName is invalid. Any other error - // option should be handled by the creationMutationHandler - if fa.Status.GameServer == nil { - review.Response.Allowed = false - review.Response.Result = &metav1.Status{ - Status: metav1.StatusFailure, - Reason: metav1.StatusReasonInvalid, - Message: "Invalid FleetAllocation", - Details: &metav1.StatusDetails{ - Name: review.Request.Name, - Group: review.Request.Kind.Group, - Kind: review.Request.Kind.Kind, - Causes: []metav1.StatusCause{ - {Type: metav1.CauseTypeFieldValueNotFound, - Message: fmt.Sprintf("Could not find fleet %s in namespace %s", fa.Spec.FleetName, review.Request.Namespace), - Field: "fleetName"}}, - }, - } - } - - return review, nil -} - -// mutationValidationHandler stops edits from happening to a -// FleetAllocation fleetName value -// nolint: dupl -func (c *Controller) mutationValidationHandler(review admv1beta1.AdmissionReview) (admv1beta1.AdmissionReview, error) { - c.logger.WithField("review", review).Info("mutationValidationHandler") - - newFA := &v1alpha1.FleetAllocation{} - oldFA := &v1alpha1.FleetAllocation{} - - if err := json.Unmarshal(review.Request.Object.Raw, newFA); err != nil { - return review, errors.Wrapf(err, "error unmarshalling new FleetAllocation json: %s", review.Request.Object.Raw) - } - - if err := json.Unmarshal(review.Request.OldObject.Raw, oldFA); err != nil { - return review, errors.Wrapf(err, "error unmarshalling old FleetAllocation json: %s", review.Request.Object.Raw) - } - - if causes, ok := oldFA.ValidateUpdate(newFA); !ok { - review.Response.Allowed = false - details := metav1.StatusDetails{ - Name: review.Request.Name, - Group: review.Request.Kind.Group, - Kind: review.Request.Kind.Kind, - Causes: causes, - } - review.Response.Result = &metav1.Status{ - Status: metav1.StatusFailure, - Message: "FleetAllocation update is invalid", - Reason: metav1.StatusReasonInvalid, - Details: &details, - } - } - - return review, nil -} - -// allocate allocated a GameServer from a given Fleet -func (c *Controller) allocate(f *v1alpha1.Fleet, fam *v1alpha1.MetaPatch) (*v1alpha1.GameServer, error) { - var allocation *v1alpha1.GameServer - // can only allocate one at a time, as we don't want two separate processes - // trying to allocate the same GameServer to different clients - c.allocationMutex.Lock() - defer c.allocationMutex.Unlock() - - // make sure we have the most up to date view of the world - if !cache.WaitForCacheSync(c.stop, c.gameServerSynced) { - return allocation, errors.New("error syncing GameServer cache") - } - gsList, err := fleets.ListGameServersByFleetOwner(c.gameServerLister, f) - if err != nil { - return allocation, err - } - - switch f.Spec.Scheduling { - case apis.Packed: - allocation = findReadyGameServerForAllocation(gsList, packedComparator) - case apis.Distributed: - allocation = findReadyGameServerForAllocation(gsList, distributedComparator) - } - - if allocation == nil { - return allocation, ErrNoGameServerReady - } - - gsCopy := allocation.DeepCopy() - gsCopy.Status.State = v1alpha1.GameServerStateAllocated - - if fam != nil { - c.patchMetadata(gsCopy, fam) - } - - gs, err := c.gameServerGetter.GameServers(f.ObjectMeta.Namespace).Update(gsCopy) - if err != nil { - return gs, errors.Wrapf(err, "error updating GameServer %s", gsCopy.ObjectMeta.Name) - } - c.recorder.Eventf(gs, corev1.EventTypeNormal, string(gs.Status.State), "Allocated from Fleet %s", f.ObjectMeta.Name) - - return gs, nil -} - -// patch the labels and annotations of an allocated GameServer with metadata from a FleetAllocation -func (c *Controller) patchMetadata(gs *v1alpha1.GameServer, fam *v1alpha1.MetaPatch) { - // patch ObjectMeta labels - if fam.Labels != nil { - if gs.ObjectMeta.Labels == nil { - gs.ObjectMeta.Labels = make(map[string]string, len(fam.Labels)) - } - for key, value := range fam.Labels { - gs.ObjectMeta.Labels[key] = value - } - } - // apply annotations patch - if fam.Annotations != nil { - if gs.ObjectMeta.Annotations == nil { - gs.ObjectMeta.Annotations = make(map[string]string, len(fam.Annotations)) - } - for key, value := range fam.Annotations { - gs.ObjectMeta.Annotations[key] = value - } - } -} diff --git a/pkg/fleetallocation/controller_test.go b/pkg/fleetallocation/controller_test.go deleted file mode 100644 index dc7a68b099..0000000000 --- a/pkg/fleetallocation/controller_test.go +++ /dev/null @@ -1,412 +0,0 @@ -// Copyright 2018 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. - -package fleetallocation - -import ( - "encoding/json" - "fmt" - "net/http" - "strconv" - "sync" - "testing" - - "agones.dev/agones/pkg/apis" - "agones.dev/agones/pkg/apis/stable/v1alpha1" - agtesting "agones.dev/agones/pkg/testing" - "agones.dev/agones/pkg/util/webhooks" - "github.com/sirupsen/logrus" - "github.com/stretchr/testify/assert" - admv1beta1 "k8s.io/api/admission/v1beta1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/watch" - k8stesting "k8s.io/client-go/testing" -) - -var ( - gvk = metav1.GroupVersionKind(v1alpha1.SchemeGroupVersion.WithKind("FleetAllocation")) -) - -func TestControllerCreationMutationHandler(t *testing.T) { - t.Parallel() - f, gsSet, gsList := defaultFixtures(3) - - fa := v1alpha1.FleetAllocation{ObjectMeta: metav1.ObjectMeta{Name: "fa-1"}, - Spec: v1alpha1.FleetAllocationSpec{FleetName: f.ObjectMeta.Name}} - - c, m := newFakeController() - - m.AgonesClient.AddReactor("list", "fleets", func(action k8stesting.Action) (bool, runtime.Object, error) { - return true, &v1alpha1.FleetList{Items: []v1alpha1.Fleet{*f}}, nil - }) - m.AgonesClient.AddReactor("list", "gameserversets", func(action k8stesting.Action) (bool, runtime.Object, error) { - return true, &v1alpha1.GameServerSetList{Items: []v1alpha1.GameServerSet{*gsSet}}, nil - }) - m.AgonesClient.AddReactor("list", "gameservers", func(action k8stesting.Action) (bool, runtime.Object, error) { - return true, &v1alpha1.GameServerList{Items: gsList}, nil - }) - - alpha1 := m.AgonesInformerFactory.Stable().V1alpha1() - fltSynced := alpha1.Fleets().Informer().HasSynced - gsSetSynced := alpha1.GameServerSets().Informer().HasSynced - gsSynced := alpha1.GameServers().Informer().HasSynced - _, cancel := agtesting.StartInformers(m, fltSynced, gsSetSynced, gsSynced) - defer cancel() - - review, err := newAdmissionReview(fa) - assert.Nil(t, err) - - result, err := c.creationMutationHandler(review) - assert.Nil(t, err) - assert.True(t, result.Response.Allowed, fmt.Sprintf("%#v", result.Response)) - assert.Equal(t, admv1beta1.PatchTypeJSONPatch, *result.Response.PatchType) - assert.Contains(t, string(result.Response.Patch), "/status/gameServer") - assert.Contains(t, string(result.Response.Patch), "/metadata/ownerReferences") -} - -func TestControllerCreationValidationHandler(t *testing.T) { - t.Parallel() - - c, _ := newFakeController() - - t.Run("fleet allocation has a gameserver", func(t *testing.T) { - fa := v1alpha1.FleetAllocation{ObjectMeta: metav1.ObjectMeta{Name: "fa-1", Namespace: "default"}, - Spec: v1alpha1.FleetAllocationSpec{FleetName: "doesnotexist"}, - Status: v1alpha1.FleetAllocationStatus{GameServer: &v1alpha1.GameServer{}}, - } - - review, err := newAdmissionReview(fa) - assert.Nil(t, err) - - result, err := c.creationValidationHandler(review) - assert.Nil(t, err) - assert.True(t, result.Response.Allowed) - }) - - t.Run("fleet allocation does not have a gameserver", func(t *testing.T) { - fa := v1alpha1.FleetAllocation{ObjectMeta: metav1.ObjectMeta{Name: "fa-1", Namespace: "default"}, - Spec: v1alpha1.FleetAllocationSpec{FleetName: "doesnotexist"}, - } - - review, err := newAdmissionReview(fa) - assert.Nil(t, err) - - result, err := c.creationValidationHandler(review) - assert.Nil(t, err) - assert.False(t, result.Response.Allowed) - assert.Equal(t, "fleetName", result.Response.Result.Details.Causes[0].Field) - }) -} - -func TestControllerMutationValidationHandler(t *testing.T) { - t.Parallel() - c, _ := newFakeController() - - fa := v1alpha1.FleetAllocation{ObjectMeta: metav1.ObjectMeta{Name: "fa-1", Namespace: "default"}, - Spec: v1alpha1.FleetAllocationSpec{FleetName: "my-fleet-name"}, - } - - t.Run("same fleetName", func(t *testing.T) { - review, err := newAdmissionReview(fa) - assert.Nil(t, err) - review.Request.OldObject = *review.Request.Object.DeepCopy() - - result, err := c.mutationValidationHandler(review) - assert.Nil(t, err) - assert.True(t, result.Response.Allowed) - }) - - t.Run("different fleetname", func(t *testing.T) { - review, err := newAdmissionReview(fa) - assert.Nil(t, err) - oldObject := fa.DeepCopy() - oldObject.Spec.FleetName = "changed" - - json, err := json.Marshal(oldObject) - assert.Nil(t, err) - review.Request.OldObject = runtime.RawExtension{Raw: json} - - result, err := c.mutationValidationHandler(review) - assert.Nil(t, err) - assert.False(t, result.Response.Allowed) - assert.Equal(t, metav1.StatusReasonInvalid, result.Response.Result.Reason) - assert.NotNil(t, result.Response.Result.Details) - }) -} - -func TestControllerAllocate(t *testing.T) { - t.Parallel() - - f, gsSet, gsList := defaultFixtures(4) - c, m := newFakeController() - n := metav1.Now() - l := map[string]string{"mode": "deathmatch"} - a := map[string]string{"map": "searide"} - fam := &v1alpha1.MetaPatch{Labels: l, Annotations: a} - - gsList[3].ObjectMeta.DeletionTimestamp = &n - - m.AgonesClient.AddReactor("list", "fleets", func(action k8stesting.Action) (bool, runtime.Object, error) { - return true, &v1alpha1.FleetList{Items: []v1alpha1.Fleet{*f}}, nil - }) - m.AgonesClient.AddReactor("list", "gameserversets", func(action k8stesting.Action) (bool, runtime.Object, error) { - return true, &v1alpha1.GameServerSetList{Items: []v1alpha1.GameServerSet{*gsSet}}, nil - }) - m.AgonesClient.AddReactor("list", "gameservers", func(action k8stesting.Action) (bool, runtime.Object, error) { - return true, &v1alpha1.GameServerList{Items: gsList}, nil - }) - - updated := false - gsWatch := watch.NewFake() - m.AgonesClient.AddWatchReactor("gameservers", k8stesting.DefaultWatchReactor(gsWatch, nil)) - m.AgonesClient.AddReactor("update", "gameservers", func(action k8stesting.Action) (bool, runtime.Object, error) { - ua := action.(k8stesting.UpdateAction) - gs := ua.GetObject().(*v1alpha1.GameServer) - updated = true - assert.Equal(t, v1alpha1.GameServerStateAllocated, gs.Status.State) - gsWatch.Modify(gs) - - return true, gs, nil - }) - - _, cancel := agtesting.StartInformers(m) - defer cancel() - - gs, err := c.allocate(f, fam) - assert.Nil(t, err) - assert.Equal(t, v1alpha1.GameServerStateAllocated, gs.Status.State) - assert.True(t, updated) - for key, value := range fam.Labels { - v, ok := gs.ObjectMeta.Labels[key] - assert.True(t, ok) - assert.Equal(t, v, value) - } - for key, value := range fam.Annotations { - v, ok := gs.ObjectMeta.Annotations[key] - assert.True(t, ok) - assert.Equal(t, v, value) - } - - updated = false - gs, err = c.allocate(f, nil) - assert.Nil(t, err) - assert.Equal(t, v1alpha1.GameServerStateAllocated, gs.Status.State) - assert.True(t, updated) - - updated = false - gs, err = c.allocate(f, nil) - assert.Nil(t, err) - assert.Equal(t, v1alpha1.GameServerStateAllocated, gs.Status.State) - assert.True(t, updated) - - updated = false - _, err = c.allocate(f, nil) - assert.NotNil(t, err) - assert.Equal(t, ErrNoGameServerReady, err) - assert.False(t, updated) -} - -func TestControllerAllocatePriority(t *testing.T) { - t.Parallel() - - n1 := "node1" - n2 := "node2" - - run := func(t *testing.T, name string, test func(t *testing.T, c *Controller, fleet *v1alpha1.Fleet)) { - f, gsSet, gsList := defaultFixtures(4) - c, m := newFakeController() - - gsList[0].Status.NodeName = n1 - gsList[1].Status.NodeName = n2 - gsList[2].Status.NodeName = n1 - gsList[3].Status.NodeName = n1 - - m.AgonesClient.AddReactor("list", "fleets", func(action k8stesting.Action) (bool, runtime.Object, error) { - return true, &v1alpha1.FleetList{Items: []v1alpha1.Fleet{*f}}, nil - }) - m.AgonesClient.AddReactor("list", "gameserversets", func(action k8stesting.Action) (bool, runtime.Object, error) { - return true, &v1alpha1.GameServerSetList{Items: []v1alpha1.GameServerSet{*gsSet}}, nil - }) - m.AgonesClient.AddReactor("list", "gameservers", func(action k8stesting.Action) (bool, runtime.Object, error) { - return true, &v1alpha1.GameServerList{Items: gsList}, nil - }) - - gsWatch := watch.NewFake() - m.AgonesClient.AddWatchReactor("gameservers", k8stesting.DefaultWatchReactor(gsWatch, nil)) - m.AgonesClient.AddReactor("update", "gameservers", func(action k8stesting.Action) (bool, runtime.Object, error) { - ua := action.(k8stesting.UpdateAction) - gs := ua.GetObject().(*v1alpha1.GameServer) - gsWatch.Modify(gs) - return true, gs, nil - }) - - _, cancel := agtesting.StartInformers(m) - defer cancel() - - t.Run(name, func(t *testing.T) { - test(t, c, f) - }) - } - - run(t, "packed", func(t *testing.T, c *Controller, f *v1alpha1.Fleet) { - // priority should be node1, then node2 - gs, err := c.allocate(f, nil) - assert.Nil(t, err) - assert.Equal(t, n1, gs.Status.NodeName) - - gs, err = c.allocate(f, nil) - assert.Nil(t, err) - assert.Equal(t, n1, gs.Status.NodeName) - - gs, err = c.allocate(f, nil) - assert.Nil(t, err) - assert.Equal(t, n1, gs.Status.NodeName) - - gs, err = c.allocate(f, nil) - assert.Nil(t, err) - assert.Equal(t, n2, gs.Status.NodeName) - - // should have none left - _, err = c.allocate(f, nil) - assert.NotNil(t, err) - }) - - run(t, "distributed", func(t *testing.T, c *Controller, f *v1alpha1.Fleet) { - // make a copy, to avoid the race check - f = f.DeepCopy() - f.Spec.Scheduling = apis.Distributed - // should go node2, then node1 - gs, err := c.allocate(f, nil) - assert.Nil(t, err) - assert.Equal(t, n2, gs.Status.NodeName) - - gs, err = c.allocate(f, nil) - assert.Nil(t, err) - assert.Equal(t, n1, gs.Status.NodeName) - - gs, err = c.allocate(f, nil) - assert.Nil(t, err) - assert.Equal(t, n1, gs.Status.NodeName) - - gs, err = c.allocate(f, nil) - assert.Nil(t, err) - assert.Equal(t, n1, gs.Status.NodeName) - - // should have none left - _, err = c.allocate(f, nil) - assert.NotNil(t, err) - }) -} - -func TestControllerAllocateMutex(t *testing.T) { - t.Parallel() - - f, gsSet, gsList := defaultFixtures(100) - c, m := newFakeController() - - m.AgonesClient.AddReactor("list", "fleets", func(action k8stesting.Action) (bool, runtime.Object, error) { - return true, &v1alpha1.FleetList{Items: []v1alpha1.Fleet{*f}}, nil - }) - m.AgonesClient.AddReactor("list", "gameserversets", func(action k8stesting.Action) (bool, runtime.Object, error) { - return true, &v1alpha1.GameServerSetList{Items: []v1alpha1.GameServerSet{*gsSet}}, nil - }) - m.AgonesClient.AddReactor("list", "gameservers", func(action k8stesting.Action) (bool, runtime.Object, error) { - return true, &v1alpha1.GameServerList{Items: gsList}, nil - }) - - //m.AgonesClient.AddReactor("update", "gameservers", func(action k8stesting.Action) (bool, runtime.Object, error) { - // ua := action.(k8stesting.UpdateAction) - // return true, ua.GetObject(), nil - //}) - - m.AgonesClient.AddWatchReactor("gameservers", k8stesting.DefaultWatchReactor(watch.NewFake(), nil)) - m.AgonesClient.AddWatchReactor("gameserversets", k8stesting.DefaultWatchReactor(watch.NewFake(), nil)) - m.AgonesClient.AddWatchReactor("fleets", k8stesting.DefaultWatchReactor(watch.NewFake(), nil)) - m.AgonesClient.AddWatchReactor("fleetallocations", k8stesting.DefaultWatchReactor(watch.NewFake(), nil)) - - _, cancel := agtesting.StartInformers(m) - defer cancel() - - wg := sync.WaitGroup{} - // start 10 threads, each one gets 10 allocations - allocate := func() { - defer wg.Done() - for i := 1; i <= 10; i++ { - _, err := c.allocate(f, nil) - assert.Nil(t, err) - } - } - - for i := 1; i <= 10; i++ { - wg.Add(1) - go allocate() - } - - logrus.Info("waiting...") - wg.Wait() -} - -func defaultFixtures(gsLen int) (*v1alpha1.Fleet, *v1alpha1.GameServerSet, []v1alpha1.GameServer) { - f := &v1alpha1.Fleet{ - ObjectMeta: metav1.ObjectMeta{ - Name: "fleet-1", - Namespace: "default", - UID: "1234", - }, - Spec: v1alpha1.FleetSpec{ - Replicas: 5, - Template: v1alpha1.GameServerTemplateSpec{}, - }, - } - f.ApplyDefaults() - gsSet := f.GameServerSet() - gsSet.ObjectMeta.Name = "gsSet1" - var gsList []v1alpha1.GameServer - for i := 1; i <= gsLen; i++ { - gs := gsSet.GameServer() - gs.ObjectMeta.Name = "gs" + strconv.Itoa(i) - gs.Status.State = v1alpha1.GameServerStateReady - gsList = append(gsList, *gs) - } - return f, gsSet, gsList -} - -// newFakeController returns a controller, backed by the fake Clientset -func newFakeController() (*Controller, agtesting.Mocks) { - m := agtesting.NewMocks() - wh := webhooks.NewWebHook(http.NewServeMux()) - c := NewController(wh, &sync.Mutex{}, m.KubeClient, m.ExtClient, m.AgonesClient, m.AgonesInformerFactory) - c.recorder = m.FakeRecorder - return c, m -} - -func newAdmissionReview(fa v1alpha1.FleetAllocation) (admv1beta1.AdmissionReview, error) { - raw, err := json.Marshal(fa) - if err != nil { - return admv1beta1.AdmissionReview{}, err - } - review := admv1beta1.AdmissionReview{ - Request: &admv1beta1.AdmissionRequest{ - Kind: gvk, - Operation: admv1beta1.Create, - Object: runtime.RawExtension{ - Raw: raw, - }, - Namespace: "default", - }, - Response: &admv1beta1.AdmissionResponse{Allowed: true}, - } - return review, err -} diff --git a/pkg/fleetallocation/doc.go b/pkg/fleetallocation/doc.go deleted file mode 100644 index ad95a89809..0000000000 --- a/pkg/fleetallocation/doc.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2018 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. - -// Package fleetallocation handles management of -// allocation GameServers from running Fleets -package fleetallocation diff --git a/pkg/fleetallocation/find.go b/pkg/fleetallocation/find.go deleted file mode 100644 index c59203fdfe..0000000000 --- a/pkg/fleetallocation/find.go +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright 2018 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. - -package fleetallocation - -import ( - "agones.dev/agones/pkg/apis/stable/v1alpha1" -) - -// nodeCount is just a convenience data structure for -// keeping relevant GameServer counts about Nodes -type nodeCount struct { - ready int64 - allocated int64 -} - -// findReadyGameServerForAllocation is a O(n) implementation to find a GameServer with priority -// defined in the comparator function. -// nolint: dupl -func findReadyGameServerForAllocation(gsList []*v1alpha1.GameServer, comparator func(bestCount, currentCount *nodeCount) bool) *v1alpha1.GameServer { - counts := map[string]*nodeCount{} - // track potential gameservers, one for each node - allocatableGameServers := map[string]*v1alpha1.GameServer{} - - // count up the number of allocated and ready game servers that exist - // also, since we're already looping through, track one Ready GameServer - // per node, so we can use that as a short list to allocate from - for _, gs := range gsList { - if gs.DeletionTimestamp.IsZero() && - (gs.Status.State == v1alpha1.GameServerStateAllocated || gs.Status.State == v1alpha1.GameServerStateReady) { - _, ok := counts[gs.Status.NodeName] - if !ok { - counts[gs.Status.NodeName] = &nodeCount{} - } - - if gs.Status.State == v1alpha1.GameServerStateAllocated { - counts[gs.Status.NodeName].allocated++ - } else if gs.Status.State == v1alpha1.GameServerStateReady { - counts[gs.Status.NodeName].ready++ - allocatableGameServers[gs.Status.NodeName] = gs - } - } - } - - // track the best node count - var bestCount *nodeCount - // the current GameServer from the node with the most GameServers (allocated, ready) - var bestGS *v1alpha1.GameServer - - for nodeName, count := range counts { - // count.ready > 0: no reason to check if we don't have ready GameServers on this node - // bestGS == nil: if there is no best GameServer, then this node & GameServer is the always the best - if count.ready > 0 && (bestGS == nil || comparator(bestCount, count)) { - bestCount = count - bestGS = allocatableGameServers[nodeName] - } - } - - return bestGS -} - -// packedComparator prioritises Nodes with GameServers that are allocated, and then Nodes with the most -// Ready GameServers -- this will bin pack allocated game servers together. -func packedComparator(bestCount, currentCount *nodeCount) bool { - if currentCount.allocated == bestCount.allocated && currentCount.ready > bestCount.ready { - return true - } else if currentCount.allocated > bestCount.allocated { - return true - } - - return false -} - -// distributedComparator is the inverse of the packed comparator, -// looking to distribute allocated gameservers on as many nodes as possible. -func distributedComparator(bestCount, currentCount *nodeCount) bool { - return !packedComparator(bestCount, currentCount) -} diff --git a/pkg/fleetallocation/find_test.go b/pkg/fleetallocation/find_test.go deleted file mode 100644 index f842373d06..0000000000 --- a/pkg/fleetallocation/find_test.go +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright 2018 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. - -package fleetallocation - -import ( - "testing" - - "agones.dev/agones/pkg/apis/stable/v1alpha1" - "github.com/stretchr/testify/assert" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -func TestFindPackedReadyGameServer(t *testing.T) { - t.Parallel() - - t.Run("test one", func(t *testing.T) { - n := metav1.Now() - - gsList := []*v1alpha1.GameServer{ - {ObjectMeta: metav1.ObjectMeta{Name: "gs6", DeletionTimestamp: &n}, Status: v1alpha1.GameServerStatus{NodeName: "node1", State: v1alpha1.GameServerStateReady}}, - {ObjectMeta: metav1.ObjectMeta{Name: "gs1"}, Status: v1alpha1.GameServerStatus{NodeName: "node1", State: v1alpha1.GameServerStateReady}}, - {ObjectMeta: metav1.ObjectMeta{Name: "gs2"}, Status: v1alpha1.GameServerStatus{NodeName: "node2", State: v1alpha1.GameServerStateReady}}, - {ObjectMeta: metav1.ObjectMeta{Name: "gs3"}, Status: v1alpha1.GameServerStatus{NodeName: "node1", State: v1alpha1.GameServerStateAllocated}}, - {ObjectMeta: metav1.ObjectMeta{Name: "gs4"}, Status: v1alpha1.GameServerStatus{NodeName: "node1", State: v1alpha1.GameServerStateAllocated}}, - {ObjectMeta: metav1.ObjectMeta{Name: "gs5"}, Status: v1alpha1.GameServerStatus{NodeName: "node1", State: v1alpha1.GameServerStateError}}, - } - - gs := findReadyGameServerForAllocation(gsList, packedComparator) - assert.Equal(t, "node1", gs.Status.NodeName) - assert.Equal(t, v1alpha1.GameServerStateReady, gs.Status.State) - // mock that the first game server is allocated - gsList[1].Status.State = v1alpha1.GameServerStateAllocated - gs = findReadyGameServerForAllocation(gsList, packedComparator) - assert.Equal(t, "node2", gs.Status.NodeName) - assert.Equal(t, v1alpha1.GameServerStateReady, gs.Status.State) - gsList[2].Status.State = v1alpha1.GameServerStateAllocated - gs = findReadyGameServerForAllocation(gsList, packedComparator) - assert.Nil(t, gs) - }) - - t.Run("allocation trap", func(t *testing.T) { - gsList := []*v1alpha1.GameServer{ - {ObjectMeta: metav1.ObjectMeta{Name: "gs1"}, Status: v1alpha1.GameServerStatus{NodeName: "node1", State: v1alpha1.GameServerStateAllocated}}, - {ObjectMeta: metav1.ObjectMeta{Name: "gs2"}, Status: v1alpha1.GameServerStatus{NodeName: "node1", State: v1alpha1.GameServerStateAllocated}}, - {ObjectMeta: metav1.ObjectMeta{Name: "gs3"}, Status: v1alpha1.GameServerStatus{NodeName: "node1", State: v1alpha1.GameServerStateAllocated}}, - {ObjectMeta: metav1.ObjectMeta{Name: "gs4"}, Status: v1alpha1.GameServerStatus{NodeName: "node1", State: v1alpha1.GameServerStateAllocated}}, - {ObjectMeta: metav1.ObjectMeta{Name: "gs5"}, Status: v1alpha1.GameServerStatus{NodeName: "node2", State: v1alpha1.GameServerStateReady}}, - {ObjectMeta: metav1.ObjectMeta{Name: "gs6"}, Status: v1alpha1.GameServerStatus{NodeName: "node2", State: v1alpha1.GameServerStateReady}}, - {ObjectMeta: metav1.ObjectMeta{Name: "gs7"}, Status: v1alpha1.GameServerStatus{NodeName: "node2", State: v1alpha1.GameServerStateReady}}, - {ObjectMeta: metav1.ObjectMeta{Name: "gs8"}, Status: v1alpha1.GameServerStatus{NodeName: "node2", State: v1alpha1.GameServerStateReady}}, - } - - gs := findReadyGameServerForAllocation(gsList, packedComparator) - assert.Equal(t, "node2", gs.Status.NodeName) - assert.Equal(t, v1alpha1.GameServerStateReady, gs.Status.State) - }) -} - -func TestFindDistributedReadyGameServer(t *testing.T) { - t.Parallel() - - n := metav1.Now() - gsList := []*v1alpha1.GameServer{ - {ObjectMeta: metav1.ObjectMeta{Name: "gs6", DeletionTimestamp: &n}, Status: v1alpha1.GameServerStatus{NodeName: "node3", State: v1alpha1.GameServerStateReady}}, - {ObjectMeta: metav1.ObjectMeta{Name: "gs1"}, Status: v1alpha1.GameServerStatus{NodeName: "node1", State: v1alpha1.GameServerStateReady}}, - {ObjectMeta: metav1.ObjectMeta{Name: "gs2"}, Status: v1alpha1.GameServerStatus{NodeName: "node1", State: v1alpha1.GameServerStateReady}}, - {ObjectMeta: metav1.ObjectMeta{Name: "gs3"}, Status: v1alpha1.GameServerStatus{NodeName: "node1", State: v1alpha1.GameServerStateReady}}, - {ObjectMeta: metav1.ObjectMeta{Name: "gs4"}, Status: v1alpha1.GameServerStatus{NodeName: "node1", State: v1alpha1.GameServerStateError}}, - {ObjectMeta: metav1.ObjectMeta{Name: "gs5"}, Status: v1alpha1.GameServerStatus{NodeName: "node2", State: v1alpha1.GameServerStateReady}}, - {ObjectMeta: metav1.ObjectMeta{Name: "gs6"}, Status: v1alpha1.GameServerStatus{NodeName: "node2", State: v1alpha1.GameServerStateReady}}, - {ObjectMeta: metav1.ObjectMeta{Name: "gs7"}, Status: v1alpha1.GameServerStatus{NodeName: "node3", State: v1alpha1.GameServerStateReady}}, - } - - gs := findReadyGameServerForAllocation(gsList, distributedComparator) - assert.Equal(t, "node3", gs.Status.NodeName) - assert.Equal(t, v1alpha1.GameServerStateReady, gs.Status.State) - - gsList[7].Status.State = v1alpha1.GameServerStateAllocated - - gs = findReadyGameServerForAllocation(gsList, distributedComparator) - assert.Equal(t, "node2", gs.Status.NodeName) - assert.Equal(t, v1alpha1.GameServerStateReady, gs.Status.State) - - gsList[5].Status.State = v1alpha1.GameServerStateAllocated - assert.Equal(t, "node2", gsList[5].Status.NodeName) - - gs = findReadyGameServerForAllocation(gsList, distributedComparator) - assert.Equal(t, "node1", gs.Status.NodeName) - assert.Equal(t, v1alpha1.GameServerStateReady, gs.Status.State) - - gsList[1].Status.State = v1alpha1.GameServerStateAllocated - - gs = findReadyGameServerForAllocation(gsList, distributedComparator) - assert.Equal(t, "node2", gs.Status.NodeName) - assert.Equal(t, v1alpha1.GameServerStateReady, gs.Status.State) - - gsList[6].Status.State = v1alpha1.GameServerStateAllocated - - gs = findReadyGameServerForAllocation(gsList, distributedComparator) - assert.Equal(t, "node1", gs.Status.NodeName) - assert.Equal(t, v1alpha1.GameServerStateReady, gs.Status.State) - - gsList[2].Status.State = v1alpha1.GameServerStateAllocated - - gs = findReadyGameServerForAllocation(gsList, distributedComparator) - assert.Equal(t, "node1", gs.Status.NodeName) - assert.Equal(t, v1alpha1.GameServerStateReady, gs.Status.State) - - gsList[3].Status.State = v1alpha1.GameServerStateAllocated - - gs = findReadyGameServerForAllocation(gsList, distributedComparator) - assert.Nil(t, gs) -} diff --git a/pkg/metrics/controller.go b/pkg/metrics/controller.go index fe2c82e602..beb955e2e7 100644 --- a/pkg/metrics/controller.go +++ b/pkg/metrics/controller.go @@ -54,12 +54,10 @@ func init() { type Controller struct { logger *logrus.Entry gameServerLister listerv1alpha1.GameServerLister - faLister listerv1alpha1.FleetAllocationLister nodeLister v1.NodeLister gameServerSynced cache.InformerSynced fleetSynced cache.InformerSynced fasSynced cache.InformerSynced - faSynced cache.InformerSynced nodeSynced cache.InformerSynced lock sync.Mutex gsCount GameServerCount @@ -76,8 +74,6 @@ func NewController( gameServer := agonesInformerFactory.Stable().V1alpha1().GameServers() gsInformer := gameServer.Informer() - fa := agonesInformerFactory.Stable().V1alpha1().FleetAllocations() - faInformer := fa.Informer() fleets := agonesInformerFactory.Stable().V1alpha1().Fleets() fInformer := fleets.Informer() fas := agonesInformerFactory.Autoscaling().V1alpha1().FleetAutoscalers() @@ -88,11 +84,9 @@ func NewController( c := &Controller{ gameServerLister: gameServer.Lister(), nodeLister: node.Lister(), - faLister: fa.Lister(), gameServerSynced: gsInformer.HasSynced, fleetSynced: fInformer.HasSynced, fasSynced: fasInformer.HasSynced, - faSynced: faInformer.HasSynced, nodeSynced: nodeInformer.HasSynced, gsCount: GameServerCount{}, faCount: map[string]int64{}, @@ -116,10 +110,6 @@ func NewController( DeleteFunc: c.recordFleetAutoScalerDeletion, }) - faInformer.AddEventHandlerWithResyncPeriod(cache.ResourceEventHandlerFuncs{ - UpdateFunc: c.recordFleetAllocationChanges, - }, 0) - gsInformer.AddEventHandlerWithResyncPeriod(cache.ResourceEventHandlerFuncs{ UpdateFunc: c.recordGameServerStatusChanges, }, 0) @@ -275,30 +265,11 @@ func (c *Controller) recordGameServerStatusChanges(old, new interface{}) { } } -// record fleet allocations total by watching cache changes. -func (c *Controller) recordFleetAllocationChanges(old, new interface{}) { - newFa, ok := new.(*stablev1alpha1.FleetAllocation) - if !ok { - return - } - oldFa, ok := old.(*stablev1alpha1.FleetAllocation) - if !ok { - return - } - // fleet allocations are added without gameserver allocated - // but then get modified on successful allocation with their gameserver - if oldFa.Status.GameServer == nil && newFa.Status.GameServer != nil { - recordWithTags(context.Background(), []tag.Mutator{tag.Upsert(keyFleetName, newFa.Spec.FleetName)}, - fleetAllocationTotalStats.M(1)) - } -} - // Run the Metrics controller. Will block until stop is closed. // Collect metrics via cache changes and parse the cache periodically to record resource counts. func (c *Controller) Run(workers int, stop <-chan struct{}) error { c.logger.Info("Wait for cache sync") - if !cache.WaitForCacheSync(stop, c.gameServerSynced, c.fleetSynced, - c.fasSynced, c.faSynced) { + if !cache.WaitForCacheSync(stop, c.gameServerSynced, c.fleetSynced, c.fasSynced) { return errors.New("failed to wait for caches to sync") } wait.Until(c.collect, MetricResyncPeriod, stop) @@ -311,33 +282,9 @@ func (c *Controller) collect() { c.lock.Lock() defer c.lock.Unlock() c.collectGameServerCounts() - c.collectFleetAllocationCounts() c.collectNodeCounts() } -// collects fleet allocations count by going through our informer cache -func (c *Controller) collectFleetAllocationCounts() { - //reset fleet allocations count per fleet name - for fleetName := range c.faCount { - c.faCount[fleetName] = 0 - } - - fleetAllocations, err := c.faLister.List(labels.Everything()) - if err != nil { - c.logger.WithError(err).Warn("failed listing fleet allocations") - return - } - - for _, fa := range fleetAllocations { - c.faCount[fa.Spec.FleetName]++ - } - - for fleetName, count := range c.faCount { - recordWithTags(context.Background(), []tag.Mutator{tag.Insert(keyFleetName, fleetName)}, - fleetAllocationCountStats.M(count)) - } -} - // collects gameservers count by going through our informer cache // this not meant to be called concurrently func (c *Controller) collectGameServerCounts() { diff --git a/pkg/metrics/controller_metrics.go b/pkg/metrics/controller_metrics.go index 84fde93d7b..46cb5ff56d 100644 --- a/pkg/metrics/controller_metrics.go +++ b/pkg/metrics/controller_metrics.go @@ -29,9 +29,7 @@ var ( fasAbleToScaleStats = stats.Int64("fas/able_to_scale", "The fleet autoscaler can access the fleet to scale (0 indicates false, 1 indicates true)", "1") fasLimitedStats = stats.Int64("fas/limited", "The fleet autoscaler is capped (0 indicates false, 1 indicates true)", "1") gameServerCountStats = stats.Int64("gameservers/count", "The count of gameservers", "1") - fleetAllocationCountStats = stats.Int64("fleet_allocations/count", "The count of fleet allocations", "1") gameServerTotalStats = stats.Int64("gameservers/total", "The total of gameservers", "1") - fleetAllocationTotalStats = stats.Int64("fleet_allocations/total", "The total of fleet allocations", "1") nodesCountStats = stats.Int64("nodes/count", "The count of nodes in the cluster", "1") gsPerNodesCountStats = stats.Int64("gameservers_node/count", "The count of gameservers per node in the cluster", "1") @@ -92,20 +90,6 @@ var ( Aggregation: view.LastValue(), TagKeys: []tag.Key{keyType, keyFleetName}, }, - &view.View{ - Name: "fleet_allocations_count", - Measure: fleetAllocationCountStats, - Description: "The number of fleet allocations", - Aggregation: view.LastValue(), - TagKeys: []tag.Key{keyFleetName}, - }, - &view.View{ - Name: "fleet_allocations_total", - Measure: fleetAllocationTotalStats, - Description: "The total of fleet allocations", - Aggregation: view.Count(), - TagKeys: []tag.Key{keyFleetName}, - }, &view.View{ Name: "gameservers_total", Measure: gameServerTotalStats, diff --git a/pkg/metrics/controller_test.go b/pkg/metrics/controller_test.go index 7973ec5bcf..874756d246 100644 --- a/pkg/metrics/controller_test.go +++ b/pkg/metrics/controller_test.go @@ -57,77 +57,6 @@ func TestControllerGameServerCount(t *testing.T) { assert.Nil(t, testutil.GatherAndCompare(registry, strings.NewReader(gsCountExpected), "agones_gameservers_count")) } -func TestControllerFleetAllocationCount(t *testing.T) { - - registry := prometheus.NewRegistry() - _, err := RegisterPrometheusExporter(registry) - assert.Nil(t, err) - - c := newFakeController() - defer c.close() - - fa1 := fleetAllocation("deleted-fleet") - c.faWatch.Add(fa1) - c.faWatch.Add(fleetAllocation("test-fleet")) - c.faWatch.Add(fleetAllocation("test-fleet")) - c.faWatch.Add(fleetAllocation("test-fleet2")) - - c.sync() - c.collect() - report() - - c.faWatch.Delete(fa1) - c.faWatch.Add(fleetAllocation("test-fleet")) - c.faWatch.Add(fleetAllocation("test-fleet2")) - - c.sync() - c.collect() - report() - - assert.Nil(t, testutil.GatherAndCompare(registry, strings.NewReader(faCountExpected), "agones_fleet_allocations_count")) -} - -func TestControllerFleetAllocationTotal(t *testing.T) { - - registry := prometheus.NewRegistry() - _, err := RegisterPrometheusExporter(registry) - assert.Nil(t, err) - - c := newFakeController() - defer c.close() - c.run(t) - // non allocated should not be counted - fa1 := fleetAllocation("unallocated") - fa1.Status.GameServer = nil - c.faWatch.Add(fa1) - c.faWatch.Delete(fa1) - - for i := 0; i < 3; i++ { - fa := fleetAllocation("test") - // only fleet allocation that were not allocated to a gameserver are collected - // this way we avoid counting multiple update events. - fa.Status.GameServer = nil - c.faWatch.Add(fa) - faUpdated := fa.DeepCopy() - faUpdated.Status.GameServer = gameServerWithFleetAndState("test", v1alpha1.GameServerStateAllocated) - c.faWatch.Modify(faUpdated) - // make sure we count only one event - c.faWatch.Modify(faUpdated) - } - for i := 0; i < 2; i++ { - fa := fleetAllocation("test2") - fa.Status.GameServer = nil - c.faWatch.Add(fa) - faUpdated := fa.DeepCopy() - faUpdated.Status.GameServer = gameServerWithFleetAndState("test2", v1alpha1.GameServerStateAllocated) - c.faWatch.Modify(faUpdated) - } - c.sync() - report() - - assert.Nil(t, testutil.GatherAndCompare(registry, strings.NewReader(faTotalExpected), "agones_fleet_allocations_total")) -} - func TestControllerGameServersTotal(t *testing.T) { registry := prometheus.NewRegistry() diff --git a/pkg/metrics/util_test.go b/pkg/metrics/util_test.go index 31365e6e89..5a54a17178 100644 --- a/pkg/metrics/util_test.go +++ b/pkg/metrics/util_test.go @@ -37,25 +37,21 @@ func newFakeController() *fakeController { m := agtesting.NewMocks() c := NewController(m.KubeClient, m.AgonesClient, m.KubeInformerFactory, m.AgonesInformerFactory) gsWatch := watch.NewFake() - faWatch := watch.NewFake() fasWatch := watch.NewFake() fleetWatch := watch.NewFake() nodeWatch := watch.NewFake() m.AgonesClient.AddWatchReactor("gameservers", k8stesting.DefaultWatchReactor(gsWatch, nil)) - m.AgonesClient.AddWatchReactor("fleetallocations", k8stesting.DefaultWatchReactor(faWatch, nil)) m.AgonesClient.AddWatchReactor("fleetautoscalers", k8stesting.DefaultWatchReactor(fasWatch, nil)) m.AgonesClient.AddWatchReactor("fleets", k8stesting.DefaultWatchReactor(fleetWatch, nil)) m.KubeClient.AddWatchReactor("nodes", k8stesting.DefaultWatchReactor(nodeWatch, nil)) - stop, cancel := agtesting.StartInformers(m, c.gameServerSynced, c.faSynced, - c.fleetSynced, c.fasSynced, c.nodeSynced) + stop, cancel := agtesting.StartInformers(m, c.gameServerSynced, c.fleetSynced, c.fasSynced, c.nodeSynced) return &fakeController{ Controller: c, Mocks: m, gsWatch: gsWatch, - faWatch: faWatch, fasWatch: fasWatch, fleetWatch: fleetWatch, nodeWatch: nodeWatch, @@ -87,15 +83,13 @@ func (c *fakeController) run(t *testing.T) { } func (c *fakeController) sync() { - cache.WaitForCacheSync(c.stop, c.gameServerSynced, c.fleetSynced, - c.fasSynced, c.faSynced) + cache.WaitForCacheSync(c.stop, c.gameServerSynced, c.fleetSynced, c.fasSynced) } type fakeController struct { *Controller agtesting.Mocks gsWatch *watch.FakeWatcher - faWatch *watch.FakeWatcher fasWatch *watch.FakeWatcher fleetWatch *watch.FakeWatcher nodeWatch *watch.FakeWatcher @@ -149,22 +143,6 @@ func generateGsEvents(count int, state v1alpha1.GameServerState, fleetName strin } } -func fleetAllocation(fleetName string) *v1alpha1.FleetAllocation { - return &v1alpha1.FleetAllocation{ - ObjectMeta: metav1.ObjectMeta{ - Name: rand.String(10), - Namespace: "default", - UID: uuid.NewUUID(), - }, - Spec: v1alpha1.FleetAllocationSpec{ - FleetName: fleetName, - }, - Status: v1alpha1.FleetAllocationStatus{ - GameServer: gameServerWithFleetAndState(fleetName, v1alpha1.GameServerStateAllocated), - }, - } -} - func fleet(fleetName string, total, allocated, ready, desired int32) *v1alpha1.Fleet { return &v1alpha1.Fleet{ ObjectMeta: metav1.ObjectMeta{ @@ -216,18 +194,6 @@ agones_gameservers_count{fleet_name="test-fleet",type="Ready"} 0 agones_gameservers_count{fleet_name="test-fleet",type="Shutdown"} 1 agones_gameservers_count{fleet_name="none",type="PortAllocation"} 2 ` -var faCountExpected = `# HELP agones_fleet_allocations_count The number of fleet allocations -# TYPE agones_fleet_allocations_count gauge -agones_fleet_allocations_count{fleet_name="test-fleet"} 3 -agones_fleet_allocations_count{fleet_name="test-fleet2"} 2 -agones_fleet_allocations_count{fleet_name="deleted-fleet"} 0 -` - -var faTotalExpected = `# HELP agones_fleet_allocations_total The total of fleet allocations -# TYPE agones_fleet_allocations_total counter -agones_fleet_allocations_total{fleet_name="test2"} 2 -agones_fleet_allocations_total{fleet_name="test"} 3 -` var gsTotalExpected = `# HELP agones_gameservers_total The total of gameservers # TYPE agones_gameservers_total counter diff --git a/pkg/util/logfields/logfields.go b/pkg/util/logfields/logfields.go index 4cf4c2d482..4b07c4cfdc 100644 --- a/pkg/util/logfields/logfields.go +++ b/pkg/util/logfields/logfields.go @@ -13,7 +13,6 @@ const ( GameServerSetKey ResourceType = "gssKey" GameServerAllocationKey ResourceType = "gsaKey" FleetKey ResourceType = "fleetKey" - FleetAllocationKey ResourceType = "faKey" FleetAutoscalerKey ResourceType = "fasKey" ) 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 e6aeb2110b..993094e52a 100644 --- a/site/content/en/docs/Reference/agones_crd_api_reference.html +++ b/site/content/en/docs/Reference/agones_crd_api_reference.html @@ -4558,7 +4558,7 @@

WebhookPolicy -{{% feature publishVersion="0.11.0" %}} +{{% feature expiryVersion="0.12.0" %}}

Packages: