-
Notifications
You must be signed in to change notification settings - Fork 775
/
gameserverset.go
151 lines (127 loc) · 5.42 KB
/
gameserverset.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
// 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 v1
import (
"agones.dev/agones/pkg/apis"
"agones.dev/agones/pkg/apis/agones"
apiequality "k8s.io/apimachinery/pkg/api/equality"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
const (
// GameServerSetGameServerLabel is the label that the name of the GameServerSet
// is set on the GameServer the GameServerSet controls
GameServerSetGameServerLabel = agones.GroupName + "/gameserverset"
)
// +genclient
// +genclient:method=GetScale,verb=get,subresource=scale,result=k8s.io/api/autoscaling/v1.Scale
// +genclient:method=UpdateScale,verb=update,subresource=scale,input=k8s.io/api/autoscaling/v1.Scale,result=k8s.io/api/autoscaling/v1.Scale
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// GameServerSet is the data structure for a set of GameServers.
// This matches philosophically with the relationship between
// Deployments and ReplicaSets
type GameServerSet struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec GameServerSetSpec `json:"spec"`
Status GameServerSetStatus `json:"status"`
}
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// GameServerSetList is a list of GameServerSet resources
type GameServerSetList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []GameServerSet `json:"items"`
}
// GameServerSetSpec the specification for GameServerSet
type GameServerSetSpec struct {
// Replicas are the number of GameServers that should be in this set
Replicas int32 `json:"replicas"`
// Scheduling strategy. Defaults to "Packed".
Scheduling apis.SchedulingStrategy `json:"scheduling,omitempty"`
// Template the GameServer template to apply for this GameServerSet
Template GameServerTemplateSpec `json:"template"`
}
// GameServerSetStatus is the status of a GameServerSet
type GameServerSetStatus struct {
// Replicas is the total number of current GameServer replicas
Replicas int32 `json:"replicas"`
// ReadyReplicas is the number of Ready GameServer replicas
ReadyReplicas int32 `json:"readyReplicas"`
// ReservedReplicas is the number of Reserved GameServer replicas
ReservedReplicas int32 `json:"reservedReplicas"`
// AllocatedReplicas is the number of Allocated GameServer replicas
AllocatedReplicas int32 `json:"allocatedReplicas"`
// ShutdownReplicas is the number of Shutdown GameServers replicas
ShutdownReplicas int32 `json:"shutdownReplicas"`
// [Stage:Alpha]
// [FeatureFlag:PlayerTracking]
// Players is the current total player capacity and count for this GameServerSet
// +optional
Players *AggregatedPlayerStatus `json:"players,omitempty"`
}
// ValidateUpdate validates when updates occur. The argument
// is the new GameServerSet, being passed into the old GameServerSet
func (gsSet *GameServerSet) ValidateUpdate(newGSS *GameServerSet) ([]metav1.StatusCause, bool) {
causes := validateName(newGSS)
if !apiequality.Semantic.DeepEqual(gsSet.Spec.Template, newGSS.Spec.Template) {
causes = append(causes, metav1.StatusCause{
Type: metav1.CauseTypeFieldValueInvalid,
Field: "template",
Message: "template values cannot be updated after creation",
})
}
return causes, len(causes) == 0
}
// Validate validates when Create occurs. Check the name size
func (gsSet *GameServerSet) Validate() ([]metav1.StatusCause, bool) {
causes := validateName(gsSet)
// check GameServer specification in a GameServerSet
gsCauses := validateGSSpec(gsSet)
if len(gsCauses) > 0 {
causes = append(causes, gsCauses...)
}
objMetaCauses := validateObjectMeta(&gsSet.Spec.Template.ObjectMeta)
if len(objMetaCauses) > 0 {
causes = append(causes, objMetaCauses...)
}
return causes, len(causes) == 0
}
// GetGameServerSpec get underlying GameServer specification
func (gsSet *GameServerSet) GetGameServerSpec() *GameServerSpec {
return &gsSet.Spec.Template.Spec
}
// GameServer returns a single GameServer derived
// from the GameServer template
func (gsSet *GameServerSet) GameServer() *GameServer {
gs := &GameServer{
ObjectMeta: *gsSet.Spec.Template.ObjectMeta.DeepCopy(),
Spec: *gsSet.Spec.Template.Spec.DeepCopy(),
}
gs.Spec.Scheduling = gsSet.Spec.Scheduling
// Switch to GenerateName, so that we always get a Unique name for the GameServer, and there
// can be no collisions
gs.ObjectMeta.GenerateName = gsSet.ObjectMeta.Name + "-"
gs.ObjectMeta.Name = ""
gs.ObjectMeta.Namespace = gsSet.ObjectMeta.Namespace
gs.ObjectMeta.ResourceVersion = ""
gs.ObjectMeta.UID = ""
ref := metav1.NewControllerRef(gsSet, SchemeGroupVersion.WithKind("GameServerSet"))
gs.ObjectMeta.OwnerReferences = append(gs.ObjectMeta.OwnerReferences, *ref)
if gs.ObjectMeta.Labels == nil {
gs.ObjectMeta.Labels = make(map[string]string, 2)
}
gs.ObjectMeta.Labels[GameServerSetGameServerLabel] = gsSet.ObjectMeta.Name
gs.ObjectMeta.Labels[FleetNameLabel] = gsSet.ObjectMeta.Labels[FleetNameLabel]
return gs
}