/
minecraft_types.go
264 lines (220 loc) · 7.74 KB
/
minecraft_types.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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
package v1alpha1
import (
"fmt"
"github.com/kmdkuk/mcing/pkg/constants"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/validation/field"
)
// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
// MinecraftSpec defines the desired state of Minecraft
type MinecraftSpec struct {
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
// Important: Run "make" to regenerate code after modifying this file
// PodTemplate is a `Pod` template for Minecraft server container.
PodTemplate PodTemplateSpec `json:"podTemplate"`
// PersistentVolumeClaimSpec is a specification of `PersistentVolumeClaim` for persisting data in minecraft.
// A claim named "minecraft-data" must be included in the list.
// +kubebuilder:validation:MinItems=1
VolumeClaimTemplates []PersistentVolumeClaim `json:"volumeClaimTemplates"`
// ServiceTemplate is a `Service` template.
// +optional
ServiceTemplate *ServiceTemplate `json:"serviceTemplate,omitempty"`
// operators on server. exec /op or /deop
// +optional
Ops Ops `json:"ops,omitempty"`
// whitelist
Whitelist Whitelist `json:"whitelist,omitempty"`
// ServerPropertiesConfigMapName is a `ConfigMap` name of `server.properties`.
// +nullable
// +optional
ServerPropertiesConfigMapName *string `json:"serverPropertiesConfigMapName,omitempty"`
// OtherConfigMapName is a `ConfigMap` name of other configurations file(eg. banned-ips.json, ops.json etc)
// +nullable
// +optional
OtherConfigMapName *string `json:"otherConfigMapName,omitempty"`
}
type Ops struct {
// user name exec /op or /deop
// +optional
Users []string `json:"users,omitempty"`
}
type Whitelist struct {
// exec /whitelist on
Enabled bool `json:"enabled"`
// user name exec /whitelist add or /whitelist remove
// +optional
Users []string `json:"users,omitempty"`
}
// PodTemplateSpec describes the data a pod should have when created from a template.
// This is slightly modified from corev1.PodTemplateSpec.
type PodTemplateSpec struct {
// Standard object's metadata. The name in this metadata is ignored.
// +optional
ObjectMeta `json:"metadata,omitempty"`
// Specification of the desired behavior of the pod.
// The name of the MySQL server container in this spec must be `minecraft`.
Spec corev1.PodSpec `json:"spec"`
}
func (p *PodTemplateSpec) ToCoreV1() corev1.PodTemplateSpec {
podTemplateSpec := corev1.PodTemplateSpec{}
podTemplateSpec.Name = p.Name
if len(p.Labels) > 0 {
podTemplateSpec.Labels = make(map[string]string)
for k, v := range p.Labels {
podTemplateSpec.Labels[k] = v
}
}
if len(p.Annotations) > 0 {
podTemplateSpec.Annotations = make(map[string]string)
for k, v := range p.Annotations {
podTemplateSpec.Annotations[k] = v
}
}
podTemplateSpec.Spec = *p.Spec.DeepCopy()
return podTemplateSpec
}
// PersistentVolumeClaim is a user's request for and claim to a persistent volume.
// This is slightly modified from corev1.PersistentVolumeClaim.
type PersistentVolumeClaim struct {
// Standard object's metadata.
ObjectMeta `json:"metadata"`
// Spec defines the desired characteristics of a volume requested by a pod author.
Spec corev1.PersistentVolumeClaimSpec `json:"spec"`
}
func (p PersistentVolumeClaim) ToCoreV1() corev1.PersistentVolumeClaim {
claim := corev1.PersistentVolumeClaim{}
claim.Name = p.Name
if len(p.Labels) > 0 {
claim.Labels = make(map[string]string)
for k, v := range p.Labels {
claim.Labels[k] = v
}
}
if len(p.Annotations) > 0 {
claim.Annotations = make(map[string]string)
for k, v := range p.Annotations {
claim.Annotations[k] = v
}
}
claim.Spec = *p.Spec.DeepCopy()
if claim.Spec.VolumeMode == nil {
modeFilesystem := corev1.PersistentVolumeFilesystem
claim.Spec.VolumeMode = &modeFilesystem
}
claim.Status.Phase = corev1.ClaimPending
return claim
}
// ServiceTemplate define the desired spec and annotations of Service
type ServiceTemplate struct {
// Standard object's metadata. Only `annotations` and `labels` are valid.
// +optional
ObjectMeta `json:"metadata,omitempty"`
// Spec is the ServiceSpec
// +optional
Spec *corev1.ServiceSpec `json:"spec,omitempty"`
}
// ObjectMeta is metadata of objects.
// This is partially copied from metav1.ObjectMeta.
type ObjectMeta struct {
// Name is the name of the object.
// +optional
Name string `json:"name,omitempty"`
// Labels is a map of string keys and values.
// +optional
Labels map[string]string `json:"labels,omitempty"`
// Annotations is a map of string keys and values.
// +optional
Annotations map[string]string `json:"annotations,omitempty"`
}
func (s MinecraftSpec) validateCreate() field.ErrorList {
var allErrs field.ErrorList
p := field.NewPath("spec")
pp := p.Child("volumeClaimTemplates")
ok := false
for i := range s.VolumeClaimTemplates {
vc := &s.VolumeClaimTemplates[i]
if vc.Name == constants.DataVolumeName {
ok = true
}
}
if !ok {
allErrs = append(allErrs, field.Required(pp, fmt.Sprintf("required volume claim template %s is missing", constants.DataVolumeName)))
}
p = p.Child("podTemplate", "spec")
pp = p.Child("containers")
minecraftIndex := -1
for i := range s.PodTemplate.Spec.Containers {
c := &s.PodTemplate.Spec.Containers[i]
if c.Name == constants.MinecraftContainerName {
minecraftIndex = i
}
}
if minecraftIndex == -1 {
allErrs = append(allErrs, field.Required(pp, fmt.Sprintf("required container %s is missing", constants.MinecraftContainerName)))
} else {
pp := p.Child("containers").Index(minecraftIndex).Child("ports")
for i := range s.PodTemplate.Spec.Containers[minecraftIndex].Ports {
port := &s.PodTemplate.Spec.Containers[minecraftIndex].Ports[i]
switch port.ContainerPort {
case constants.ServerPort, constants.RconPort:
allErrs = append(allErrs, field.Invalid(pp.Index(i), port.ContainerPort, "reserved port"))
}
switch port.Name {
case constants.ServerPortName, constants.RconPortName:
allErrs = append(allErrs, field.Invalid(pp.Index(i), port.Name, "reserved port name"))
}
}
pp = p.Child("containers").Index(minecraftIndex).Child("env")
hasEula := false
for i := range s.PodTemplate.Spec.Containers[minecraftIndex].Env {
env := &s.PodTemplate.Spec.Containers[minecraftIndex].Env[i]
switch env.Name {
case constants.EulaEnvName:
hasEula = true
}
}
if !hasEula {
allErrs = append(allErrs, field.Required(pp, "EULA is required. The server will not start unless EULA=true."))
}
}
return allErrs
}
func (s MinecraftSpec) validateUpdate(old MinecraftSpec) field.ErrorList {
var allErrs field.ErrorList
return append(allErrs, s.validateCreate()...)
}
// MinecraftStatus defines the observed state of Minecraft
type MinecraftStatus struct {
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
// Important: Run "make" to regenerate code after modifying this file
}
//+kubebuilder:object:root=true
//+kubebuilder:subresource:status
// Minecraft is the Schema for the minecrafts API
type Minecraft struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec MinecraftSpec `json:"spec,omitempty"`
Status MinecraftStatus `json:"status,omitempty"`
}
func (m *Minecraft) PrefixedName() string {
return "mcing-" + m.Name
}
func (m *Minecraft) PodName() string {
return m.PrefixedName() + "-0"
}
func (m *Minecraft) HeadlessServiceName() string {
return m.PrefixedName() + "-headless"
}
//+kubebuilder:object:root=true
// MinecraftList contains a list of Minecraft
type MinecraftList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []Minecraft `json:"items"`
}
func init() {
SchemeBuilder.Register(&Minecraft{}, &MinecraftList{})
}