-
Notifications
You must be signed in to change notification settings - Fork 783
/
gameserverset.go
142 lines (118 loc) · 5.03 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
// 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 (
"reflect"
"agones.dev/agones/pkg/apis"
"agones.dev/agones/pkg/apis/agones"
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/extensions/v1beta1.Scale
// +genclient:method=UpdateScale,verb=update,subresource=scale,input=k8s.io/api/extensions/v1beta1.Scale,result=k8s.io/api/extensions/v1beta1.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
// Depoyments 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 the total number of current GameServer replicas
Replicas int32 `json:"replicas"`
// ReadyReplicas are the number of Ready GameServer replicas
ReadyReplicas int32 `json:"readyReplicas"`
// ReservedReplicas are the number of Reserved GameServer replicas
ReservedReplicas int32 `json:"reservedReplicas"`
// AllocatedReplicas are the number of Allocated GameServer replicas
AllocatedReplicas int32 `json:"allocatedReplicas"`
// ShutdownReplicas are the number of Shutdown GameServers replicas
ShutdownReplicas int32 `json:"shutdownReplicas"`
}
// ValidateUpdate validates when updates occur. The argument
// is the new GameServerSet, being passed into the old GameServerSet
func (gsSet *GameServerSet) ValidateUpdate(new *GameServerSet) ([]metav1.StatusCause, bool) {
causes := validateName(new)
if !reflect.DeepEqual(gsSet.Spec.Template, new.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 occur. 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...)
}
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 GameSever 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
}