blob: a3cd3d36923c784d2aab55715431d2e78af24ae9 [file] [log] [blame]
Sergiusz Bazanskib7fcc672019-04-01 18:40:50 +02001# Deploy Rook/Ceph Operator
2
3local kube = import "../../../kube/kube.libsonnet";
Sergiusz Bazanskia01c4872019-09-05 18:00:02 +02004local policies = import "../../../kube/policies.libsonnet";
Sergiusz Bazanskib7fcc672019-04-01 18:40:50 +02005
Sergiusz Bazanskid436de22020-02-21 17:10:42 +01006local oa = kube.OpenAPI;
7
Sergiusz Bazanskib7fcc672019-04-01 18:40:50 +02008{
Sergiusz Bazanskic6da1272019-04-02 00:06:13 +02009 Operator: {
Sergiusz Bazanskib7fcc672019-04-01 18:40:50 +020010 local env = self,
11 local cfg = env.cfg,
12 cfg:: {
Serge Bazanski464fb042021-09-11 20:24:27 +000013 image: "rook/ceph:v1.6.9",
Sergiusz Bazanskib7fcc672019-04-01 18:40:50 +020014 namespace: "rook-ceph-system",
15 },
16
17 metadata:: {
18 namespace: cfg.namespace,
19 labels: {
20 "operator": "rook",
21 "storage-backend": "ceph",
22 },
23 },
24
25 namespace: kube.Namespace(cfg.namespace),
26
Sergiusz Bazanskia01c4872019-09-05 18:00:02 +020027 policyInsecure: policies.AllowNamespaceInsecure(cfg.namespace),
28
Serge Bazanski464fb042021-09-11 20:24:27 +000029 // Grab CRDs from upstream YAML.
30 //
31 // We use a bit of jsonnet to remove some fields that kubebuilder (used
32 // upstream) added and to override preserveUnknownFIelds (as some older
33 // deployment apparently set it to true, which doesn't work for new
34 // CRDs that have default values).
35 crds: [
36 (el {
37 metadata+: {
38 annotations:: null,
39 creationTimestamp:: null,
Sergiusz Bazanskib7fcc672019-04-01 18:40:50 +020040 },
Serge Bazanski464fb042021-09-11 20:24:27 +000041 status:: null,
Sergiusz Bazanskib7fcc672019-04-01 18:40:50 +020042 spec+: {
Serge Bazanski464fb042021-09-11 20:24:27 +000043 preserveUnknownFields: false,
Sergiusz Bazanskib7fcc672019-04-01 18:40:50 +020044 },
Serge Bazanski464fb042021-09-11 20:24:27 +000045 })
46 for el in (std.native("parseYaml")(importstr "rook-crds.yaml")) if el != null
47 ],
Sergiusz Bazanskib7fcc672019-04-01 18:40:50 +020048
Sergiusz Bazanskid436de22020-02-21 17:10:42 +010049 sa: {
50 system: kube.ServiceAccount("rook-ceph-system") {
51 metadata+: env.metadata,
52 },
53 csiCephfsPlugin: kube.ServiceAccount("rook-csi-cephfs-plugin-sa") {
54 metadata+: env.metadata,
55 },
56 csiCephfsProvisioner: kube.ServiceAccount("rook-csi-cephfs-provisioner-sa") {
57 metadata+: env.metadata,
58 },
59 csiRbdPlugin: kube.ServiceAccount("rook-csi-rbd-plugin-sa") {
60 metadata+: env.metadata,
61 },
62 csiRbdProvisioner: kube.ServiceAccount("rook-csi-rbd-provisioner-sa") {
63 metadata+: env.metadata,
64 },
Sergiusz Bazanskicdfafaf2019-04-01 19:16:18 +020065 },
66
67 crs: {
68 clusterMgmt: kube.ClusterRole("rook-ceph-cluster-mgmt") {
Sergiusz Bazanskic6da1272019-04-02 00:06:13 +020069 metadata+: env.metadata { namespace:: null },
Sergiusz Bazanskicdfafaf2019-04-01 19:16:18 +020070 rules: [
71 {
Serge Bazanski464fb042021-09-11 20:24:27 +000072 apiGroups: ["", "apps", "extensions"],
73 resources: ["secrets", "pods", "pods/log", "services", "configmaps", "deployments", "daemonsets"],
Sergiusz Bazanskicdfafaf2019-04-01 19:16:18 +020074 verbs: ["get", "list", "watch", "patch", "create", "update", "delete"],
75 },
Sergiusz Bazanskicdfafaf2019-04-01 19:16:18 +020076 ],
77 },
78 global: kube.ClusterRole("rook-ceph-global") {
Serge Bazanski464fb042021-09-11 20:24:27 +000079 metadata+: env.metadata {
80 namespace:: null,
81 labels+: {
82 "rbac.ceph.rook.io/aggregate-to-rook-ceph-global": "true",
83 },
84 },
Sergiusz Bazanskicdfafaf2019-04-01 19:16:18 +020085 rules: [
86 {
87 apiGroups: [""],
Serge Bazanski464fb042021-09-11 20:24:27 +000088 resources: ["pods", "nodes", "nodes/proxy", "services"],
Sergiusz Bazanskicdfafaf2019-04-01 19:16:18 +020089 verbs: ["get", "list", "watch"],
90 },
91 {
92 apiGroups: [""],
93 resources: ["events", "persistentvolumes", "persistentvolumeclaims", "endpoints"],
94 verbs: ["get", "list", "watch", "patch", "create", "update", "delete"],
95 },
96 {
97 apiGroups: ["storage.k8s.io"],
98 resources: ["storageclasses"],
Sergiusz Bazanskid436de22020-02-21 17:10:42 +010099 verbs: ["get", "list", "watch"],
Sergiusz Bazanskicdfafaf2019-04-01 19:16:18 +0200100 },
101 {
Sergiusz Bazanskic6da1272019-04-02 00:06:13 +0200102 apiGroups: ["batch"],
Serge Bazanski464fb042021-09-11 20:24:27 +0000103 resources: ["jobs", "cronjobs"],
Sergiusz Bazanskic6da1272019-04-02 00:06:13 +0200104 verbs: ["get", "list", "watch", "create", "update", "delete"],
105 },
106 {
Sergiusz Bazanskicdfafaf2019-04-01 19:16:18 +0200107 apiGroups: ["ceph.rook.io"],
108 resources: ["*"],
109 verbs: ["*"],
110 },
111 {
112 apiGroups: ["rook.io"],
113 resources: ["*"],
114 verbs: ["*"],
115 },
Sergiusz Bazanskid436de22020-02-21 17:10:42 +0100116 {
Serge Bazanski464fb042021-09-11 20:24:27 +0000117 apiGroups: ["policy", "apps", "extensions"],
Serge Bazanski2c04c842021-01-19 21:41:11 +0100118 resources: ["poddisruptionbudgets", "deployments", "replicasets"],
Sergiusz Bazanskid436de22020-02-21 17:10:42 +0100119 verbs: ["*"],
120 },
Serge Bazanski2c04c842021-01-19 21:41:11 +0100121 {
122 apiGroups: ["healthchecking.openshift.io"],
123 resources: ["machinedisruptionbudgets"],
124 verbs: ["get", "list", "watch", "create", "update", "delete"],
125 },
126 {
127 apiGroups: ["machine.openshift.io"],
128 resources: ["machines"],
129 verbs: ["get", "list", "watch", "create", "update", "delete"],
130 },
131 {
132 apiGroups: ["storage.k8s.io"],
133 resources: ["csidrivers"],
Serge Bazanski464fb042021-09-11 20:24:27 +0000134 verbs: ["create", "delete", "get", "update"],
135 },
136 {
137 apiGroups: ["k8s.cni.cncf.io"],
138 resources: ["network-attachment-definitions"],
139 verbs: ["get"],
Serge Bazanski2c04c842021-01-19 21:41:11 +0100140 },
Sergiusz Bazanskicdfafaf2019-04-01 19:16:18 +0200141 ],
142 },
Sergiusz Bazanskid436de22020-02-21 17:10:42 +0100143
Sergiusz Bazanskicdfafaf2019-04-01 19:16:18 +0200144 mgrCluster: kube.ClusterRole("rook-ceph-mgr-cluster") {
Sergiusz Bazanskic6da1272019-04-02 00:06:13 +0200145 metadata+: env.metadata { namespace:: null },
Sergiusz Bazanskicdfafaf2019-04-01 19:16:18 +0200146 rules: [
147 {
148 apiGroups: [""],
149 resources: ["configmaps", "nodes", "nodes/proxy"],
150 verbs: ["get", "list", "watch"],
151 },
Sergiusz Bazanskid436de22020-02-21 17:10:42 +0100152 {
153 apiGroups: [""],
154 resources: ["events"],
155 verbs: ["create", "patch", "list", "get", "watch"],
156 },
Sergiusz Bazanskicdfafaf2019-04-01 19:16:18 +0200157 ]
158 },
Sergiusz Bazanskid436de22020-02-21 17:10:42 +0100159 objectBucket: kube.ClusterRole("rook-ceph-object-bucket") {
160 metadata+: env.metadata {
161 namespace:: null,
Sergiusz Bazanskid436de22020-02-21 17:10:42 +0100162 },
163 rules: [
164 {
165 apiGroups: [""],
166 resources: ["secrets", "configmaps"],
167 verbs: ["*"],
168 },
169 {
170 apiGroups: ["storage.k8s.io"],
171 resources: ["storageclasses"],
172 verbs: ["get", "list", "watch"],
173 },
174 {
175 apiGroups: ["objectbucket.io"],
176 resources: ["*"],
177 verbs: ["*"],
178 },
179 ],
180 },
181
182 cephfsCSINodeplugin: kube.ClusterRole("cephfs-csi-nodeplugin") {
183 metadata+: env.metadata { namespace:: null },
184 rules: [
185 {
186 apiGroups: [""],
187 resources: ["nodes"],
188 verbs: ["get", "list", "update"],
189 },
190 {
191 apiGroups: [""],
192 resources: ["namespaces"],
193 verbs: ["get", "list"],
194 },
195 {
196 apiGroups: [""],
197 resources: ["persistentvolumes"],
198 verbs: ["get", "list", "watch", "update"],
199 },
200 {
201 apiGroups: ["storage.k8s.io"],
202 resources: ["volumeattachments"],
203 verbs: ["get", "list", "watch", "update"],
204 },
205 {
206 apiGroups: [""],
207 resources: ["configmaps"],
208 verbs: ["get", "list"],
209 },
210 ],
211 },
212
213 cephfsExternalProvisionerRunner: kube.ClusterRole("cephfs-external-provisioner-runner") {
Serge Bazanski464fb042021-09-11 20:24:27 +0000214 metadata+: env.metadata {
215 namespace:: null,
216 labels+: {
217 "rbac.ceph.rook.io/aggregate-to-cephfs-external-provisioner-runner": "true",
218 },
219 },
Sergiusz Bazanskid436de22020-02-21 17:10:42 +0100220 rules: [
221 {
222 apiGroups: [""],
223 resources: ["secrets"],
224 verbs: ["get", "list"],
225 },
226 {
227 apiGroups: [""],
228 resources: ["persistentvolumes"],
Serge Bazanski464fb042021-09-11 20:24:27 +0000229 verbs: ["get", "list", "watch", "create", "delete", "update", "patch"],
Sergiusz Bazanskid436de22020-02-21 17:10:42 +0100230 },
231 {
232 apiGroups: [""],
233 resources: ["persistentvolumeclaims"],
234 verbs: ["get", "list", "watch", "update"],
235 },
236 {
237 apiGroups: ["storage.k8s.io"],
238 resources: ["storageclasses"],
239 verbs: ["get", "list", "watch"],
240 },
241 {
242 apiGroups: [""],
243 resources: ["events"],
244 verbs: ["list", "watch", "create", "update", "patch"],
245 },
246 {
Serge Bazanski464fb042021-09-11 20:24:27 +0000247 apiGroups: ["snapshot.storage.k8s.io"],
248 resources: ["volumesnapshots"],
249 verbs: ["get", "list", "watch", "update"],
250 },
251 {
252 apiGroups: ["snapshot.storage.k8s.io"],
253 resources: ["volumesnapshotcontents"],
254 verbs: ["create", "get", "list", "watch", "update", "delete"],
255 },
256 {
257 apiGroups: ["snapshot.storage.k8s.io"],
258 resources: ["volumesnapshotclasses"],
259 verbs: ["get", "list", "watch"],
260 },
261 {
262 apiGroups: ["snapshot.storage.k8s.io"],
263 resources: ["volumesnapshotcontents/status"],
264 verbs: ["update"],
265 },
266 {
267 apiGroups: ["apiextensions.k8s.io"],
268 resources: ["customresourcedefinitions"],
269 verbs: ["create", "list", "watch", "delete", "get", "update"],
270 },
271 {
272 apiGroups: ["snapshot.storage.k8s.io"],
273 resources: ["volumesnapshots/status"],
274 verbs: ["update"],
275 },
276 {
Sergiusz Bazanskid436de22020-02-21 17:10:42 +0100277 apiGroups: ["storage.k8s.io"],
278 resources: ["volumeattachments"],
Serge Bazanski464fb042021-09-11 20:24:27 +0000279 verbs: ["get", "list", "watch", "update", "patch"],
280 },
281 {
282 apiGroups: ["storage.k8s.io"],
283 resources: ["volumeattachments/status"],
284 verbs: ["patch"],
Sergiusz Bazanskid436de22020-02-21 17:10:42 +0100285 },
286 {
287 apiGroups: [""],
288 resources: ["nodes"],
289 verbs: ["get", "list", "watch"],
290 },
Serge Bazanski464fb042021-09-11 20:24:27 +0000291 {
292 apiGroups: [""],
293 resources: ["persistentvolumeclaims/status"],
294 verbs: ["update", "patch"],
295 },
Sergiusz Bazanskid436de22020-02-21 17:10:42 +0100296 ],
297 },
298
299 rbdCSINodeplugin: kube.ClusterRole("rbd-csi-nodeplugin") {
300 metadata+: env.metadata { namespace:: null },
301 rules: [
302 {
303 apiGroups: [""],
304 resources: ["secrets"],
305 verbs: ["get", "list"],
306 },
307 {
308 apiGroups: [""],
309 resources: ["nodes"],
310 verbs: ["get", "list", "update"],
311 },
312 {
313 apiGroups: [""],
314 resources: ["namespaces"],
315 verbs: ["get", "list"],
316 },
317 {
318 apiGroups: [""],
319 resources: ["persistentvolumes"],
320 verbs: ["get", "list", "watch", "update"],
321 },
322 {
323 apiGroups: ["storage.k8s.io"],
324 resources: ["volumeattachments"],
325 verbs: ["get", "list", "watch", "update"],
326 },
327 {
328 apiGroups: [""],
329 resources: ["configmaps"],
330 verbs: ["get", "list"],
331 },
332 ],
333 },
334
335 rbdExternalProvisionerRunner: kube.ClusterRole("rbd-external-provisioner-runner") {
Serge Bazanski464fb042021-09-11 20:24:27 +0000336 metadata+: env.metadata {
337 namespace:: null,
338 labels+: {
339 "rbac.ceph.rook.io/aggregate-to-rbd-external-provisioner-runner": "true",
340 },
341 },
Sergiusz Bazanskid436de22020-02-21 17:10:42 +0100342 rules: [
343 {
344 apiGroups: [""],
345 resources: ["secrets"],
Serge Bazanski464fb042021-09-11 20:24:27 +0000346 verbs: ["get", "list", "watch"],
Sergiusz Bazanskid436de22020-02-21 17:10:42 +0100347 },
348 {
349 apiGroups: [""],
350 resources: ["persistentvolumes"],
Serge Bazanski464fb042021-09-11 20:24:27 +0000351 verbs: ["get", "list", "watch", "create", "delete", "update", "patch"],
Sergiusz Bazanskid436de22020-02-21 17:10:42 +0100352 },
353 {
354 apiGroups: [""],
355 resources: ["persistentvolumeclaims"],
356 verbs: ["get", "list", "watch", "update"],
357 },
358 {
359 apiGroups: ["storage.k8s.io"],
360 resources: ["volumeattachments"],
Serge Bazanski464fb042021-09-11 20:24:27 +0000361 verbs: ["get", "list", "watch", "update", "patch"],
362 },
363 {
364 apiGroups: ["storage.k8s.io"],
365 resources: ["volumeattachments/status"],
366 verbs: ["patch"],
Sergiusz Bazanskid436de22020-02-21 17:10:42 +0100367 },
368 {
369 apiGroups: [""],
370 resources: ["nodes"],
371 verbs: ["get", "list", "watch"],
372 },
373 {
374 apiGroups: ["storage.k8s.io"],
375 resources: ["storageclasses"],
376 verbs: ["get", "list", "watch"]
377 },
378 {
379 apiGroups: [""],
380 resources: ["events"],
381 verbs: ["list", "watch", "create", "update", "patch"],
382 },
383 {
384 apiGroups: ["snapshot.storage.k8s.io"],
Serge Bazanski464fb042021-09-11 20:24:27 +0000385 resources: ["volumesnapshots"],
386 verbs: ["get", "list", "watch", "update"],
387 },
388 {
389 apiGroups: ["snapshot.storage.k8s.io"],
Sergiusz Bazanskid436de22020-02-21 17:10:42 +0100390 resources: ["volumesnapshotcontents"],
391 verbs: ["create", "get", "list", "watch", "update", "delete"],
392 },
393 {
394 apiGroups: ["snapshot.storage.k8s.io"],
395 resources: ["volumesnapshotclasses"],
396 verbs: ["get", "list", "watch"],
397 },
398 {
Serge Bazanski464fb042021-09-11 20:24:27 +0000399 apiGroups: ["snapshot.storage.k8s.io"],
400 resources: ["volumesnapshotcontents/status"],
401 verbs: ["update"],
402 },
403 {
Sergiusz Bazanskid436de22020-02-21 17:10:42 +0100404 apiGroups: ["apiextensions.k8s.io"],
405 resources: ["customresourcedefinitions"],
406 verbs: ["create", "list", "watch", "delete", "get", "update"],
407 },
408 {
409 apiGroups: ["snapshot.storage.k8s.io"],
410 resources: ["volumesnapshots/status"],
411 verbs: ["update"],
412 },
Serge Bazanski464fb042021-09-11 20:24:27 +0000413 {
414 apiGroups: [""],
415 resources: ["persistentvolumeclaims/status"],
416 verbs: ["update", "patch"],
417 },
418 {
419 apiGroups: [""],
420 resources: ["configmaps"],
421 verbs: ["get"],
422 },
423 {
424 apiGroups: ["replication.storage.openshift.io"],
425 resources: ["volumereplications", "volumereplicationclasses"],
426 verbs: ["create", "delete", "get", "list", "patch", "update", "watch"],
427 },
428 {
429 apiGroups: ["replication.storage.openshift.io"],
430 resources: ["volumereplications/finalizers"],
431 verbs: ["update"],
432 },
433 {
434 apiGroups: ["replication.storage.openshift.io"],
435 resources: ["volumereplications/status"],
436 verbs: ["get", "patch", "update"],
437 },
438 {
439 apiGroups: ["replication.storage.openshift.io"],
440 resources: ["volumereplicationclasses/status"],
441 verbs: ["get"],
442 },
Sergiusz Bazanskid436de22020-02-21 17:10:42 +0100443 ],
444 },
Sergiusz Bazanskicdfafaf2019-04-01 19:16:18 +0200445 },
446
Sergiusz Bazanskid436de22020-02-21 17:10:42 +0100447 crbs: {
448 global: kube.ClusterRoleBinding("ceph-rook-global") {
449 metadata+: env.metadata { namespace:: null },
450 roleRef_: env.crs.global,
451 subjects_: [env.sa.system],
452 },
453 objectBucket: kube.ClusterRoleBinding("rook-ceph-object-bucket") {
454 metadata+: env.metadata { namespace:: null },
455 roleRef_: env.crs.objectBucket,
456 subjects_: [env.sa.system],
457 },
Serge Bazanski464fb042021-09-11 20:24:27 +0000458 cephfsCSINodeplugin: kube.ClusterRoleBinding("cephfs-csi-nodeplugin") {
Sergiusz Bazanskid436de22020-02-21 17:10:42 +0100459 metadata+: env.metadata { namespace:: null },
460 roleRef_: env.crs.cephfsCSINodeplugin,
461 subjects_: [env.sa.csiCephfsPlugin],
462 },
463 cephfsCSIProvisioner: kube.ClusterRoleBinding("cephfs-csi-provisioner") {
464 metadata+: env.metadata { namespace:: null },
465 roleRef_: env.crs.cephfsExternalProvisionerRunner,
466 subjects_: [env.sa.csiCephfsProvisioner],
467 },
468 rbdCSINodeplugin: kube.ClusterRoleBinding("rbd-csi-nodeplugin") {
469 metadata+: env.metadata { namespace:: null },
470 roleRef_: env.crs.rbdCSINodeplugin,
471 subjects_: [env.sa.csiRbdPlugin],
472 },
473 rbdCSIProvisioner: kube.ClusterRoleBinding("rbd-csi-provisioner") {
474 metadata+: env.metadata { namespace:: null },
475 roleRef_: env.crs.rbdExternalProvisionerRunner,
476 subjects_: [env.sa.csiRbdProvisioner],
477 },
Sergiusz Bazanskicdfafaf2019-04-01 19:16:18 +0200478 },
479
Sergiusz Bazanskid436de22020-02-21 17:10:42 +0100480 roles: {
481 system: kube.Role("ceph-rook-system") {
482 metadata+: env.metadata,
483 rules: [
484 {
485 apiGroups: [""],
486 resources: ["pods", "configmaps", "services"],
487 verbs: ["get", "list", "watch", "patch", "create", "update", "delete"],
488 },
489 {
490 apiGroups: ["apps"],
Serge Bazanski464fb042021-09-11 20:24:27 +0000491 resources: ["daemonsets", "statefulsets", "deployments"],
Sergiusz Bazanskid436de22020-02-21 17:10:42 +0100492 verbs: ["get", "list", "watch", "create", "update", "delete"],
493 },
Serge Bazanski464fb042021-09-11 20:24:27 +0000494 {
495 apiGroups: ["k8s.cni.cncf.io"],
496 resources: ["network-attachment-definitions"],
497 verbs: ["get"],
498 },
Sergiusz Bazanskid436de22020-02-21 17:10:42 +0100499 ],
500 },
501 cephfsExternalProvisioner: kube.Role("cephfs-external-provisioner-cfg") {
502 metadata+: env.metadata,
503 rules: [
504 {
505 apiGroups: [""],
506 resources: ["endpoints"],
507 verbs: ["get", "watch", "list", "delete", "update", "create"],
508 },
509 {
510 apiGroups: [""],
511 resources: ["configmaps"],
512 verbs: ["get", "list", "create", "delete"],
513 },
514 {
515 apiGroups: ["coordination.k8s.io"],
516 resources: ["leases"],
517 verbs: ["get" ,"watch", "list", "delete", "update", "create"],
518 },
519 ],
520 },
521 rbdExternalProvisioner: kube.Role("rbd-external-provisioner-cfg") {
522 metadata+: env.metadata,
523 rules: [
524 {
525 apiGroups: [""],
526 resources: ["endpoints"],
527 verbs: ["get", "watch", "list", "delete", "update", "create"],
528 },
529 {
530 apiGroups: [""],
531 resources: ["configmaps"],
Serge Bazanski464fb042021-09-11 20:24:27 +0000532 verbs: ["get", "list", "watch", "create", "delete", "update"],
Sergiusz Bazanskid436de22020-02-21 17:10:42 +0100533 },
534 {
535 apiGroups: ["coordination.k8s.io"],
536 resources: ["leases"],
537 verbs: ["get" ,"watch", "list", "delete", "update", "create"],
538 },
539 ],
540 },
Sergiusz Bazanskicdfafaf2019-04-01 19:16:18 +0200541 },
542
Sergiusz Bazanskid436de22020-02-21 17:10:42 +0100543 rbs: {
544 system: kube.RoleBinding("ceph-rook-system") {
545 metadata+: env.metadata,
546 roleRef_: env.roles.system,
547 subjects_: [env.sa.system],
548 },
549 cephfsCSIProvisioner: kube.RoleBinding("cephfs-csi-provisioner-role-cfg") {
550 metadata+: env.metadata,
551 roleRef_: env.roles.cephfsExternalProvisioner,
552 subjects_: [env.sa.csiCephfsProvisioner],
553 },
554 rbdCSIProvisioner: kube.RoleBinding("rbd-csi-provisioner-role-cfg") {
555 metadata+: env.metadata,
556 roleRef_: env.roles.rbdExternalProvisioner,
557 subjects_: [env.sa.csiRbdProvisioner],
558 },
Sergiusz Bazanskicdfafaf2019-04-01 19:16:18 +0200559 },
560
561 operator: kube.Deployment("rook-ceph-operator") {
562 metadata+: env.metadata,
563 spec+: {
564 template+: {
565 spec+: {
Sergiusz Bazanskid436de22020-02-21 17:10:42 +0100566 serviceAccountName: env.sa.system.metadata.name,
Sergiusz Bazanskicdfafaf2019-04-01 19:16:18 +0200567 containers_: {
568 operator: kube.Container("rook-ceph-operator") {
569 image: cfg.image,
570 args: ["ceph", "operator"],
571 volumeMounts_: {
572 "rook-config": { mountPath: "/var/lib/rook" },
573 "default-config-dir": { mountPath: "/etc/ceph" },
574 },
575 env_: {
576 LIB_MODULES_DIR_PATH: "/run/current-system/kernel-modules/lib/modules/",
577 ROOK_ALLOW_MULTIPLE_FILESYSTEMS: "false",
Sergiusz Bazanski321fad92019-04-19 14:14:36 +0200578 ROOK_LOG_LEVEL: "INFO",
Sergiusz Bazanskicdfafaf2019-04-01 19:16:18 +0200579 ROOK_MON_HEALTHCHECK_INTERVAL: "45s",
580 ROOK_MON_OUT_TIMEOUT: "600s",
581 ROOK_DISCOVER_DEVICES_INTERVAL: "60m",
582 ROOK_HOSTPATH_REQUIRES_PRIVILEGED: "false",
583 ROOK_ENABLE_SELINUX_RELABELING: "true",
584 ROOK_ENABLE_FSGROUP: "true",
585 NODE_NAME: kube.FieldRef("spec.nodeName"),
586 POD_NAME: kube.FieldRef("metadata.name"),
587 POD_NAMESPACE: kube.FieldRef("metadata.namespace"),
Serge Bazanski4b8ee322021-09-14 21:30:57 +0200588 ROOK_CSI_KUBELET_DIR_PATH: "/var/lib/kubernetes",
589 ROOK_ENABLE_FLEX_DRIVER: "true",
Sergiusz Bazanskicdfafaf2019-04-01 19:16:18 +0200590 },
591 },
592 },
593 volumes_: {
594 "rook-config": { emptyDir: {} },
595 "default-config-dir": { emptyDir: {} },
596 },
597 },
598 },
599 },
600 },
Sergiusz Bazanskib7fcc672019-04-01 18:40:50 +0200601 },
Sergiusz Bazanskic6da1272019-04-02 00:06:13 +0200602
603 // Create a new Ceph cluster in a new namespace.
604 Cluster(operator, name):: {
605 local cluster = self,
606 spec:: error "please define cluster spec",
607
608
609 metadata:: {
610 namespace: name,
611 },
612
613 name(suffix):: cluster.metadata.namespace + "-" + suffix,
614
615 namespace: kube.Namespace(cluster.metadata.namespace),
616
617 sa: {
618 // service accounts need to be hardcoded, see operator source.
619 osd: kube.ServiceAccount("rook-ceph-osd") {
620 metadata+: cluster.metadata,
621 },
622 mgr: kube.ServiceAccount("rook-ceph-mgr") {
623 metadata+: cluster.metadata,
624 },
Sergiusz Bazanskid436de22020-02-21 17:10:42 +0100625 cmdReporter: kube.ServiceAccount("rook-ceph-cmd-reporter") {
626 metadata+: cluster.metadata,
627 },
Sergiusz Bazanskic6da1272019-04-02 00:06:13 +0200628 },
629
630 roles: {
631 osd: kube.Role(cluster.name("osd")) {
632 metadata+: cluster.metadata,
633 rules: [
634 {
635 apiGroups: [""],
636 resources: ["configmaps"],
637 verbs: ["get", "list", "watch", "create", "update", "delete"],
Serge Bazanski2c04c842021-01-19 21:41:11 +0100638 },
639 ],
640 },
641 osdCluster: kube.ClusterRole(cluster.name("osd-cluster")) {
642 metadata+: cluster.metadata { namespace:: null },
643 rules: [
644 {
645 apiGroups: [""],
646 resources: ["nodes"],
647 verbs: ["get", "list"],
648 },
Sergiusz Bazanskic6da1272019-04-02 00:06:13 +0200649 ],
650 },
651 mgr: kube.Role(cluster.name("mgr")) {
652 metadata+: cluster.metadata,
653 rules: [
654 {
655 apiGroups: [""],
656 resources: ["pods", "services"],
657 verbs: ["get", "list", "watch"],
658 },
659 {
660 apiGroups: ["batch"],
661 resources: ["jobs"],
662 verbs: ["get", "list", "watch", "create", "update", "delete"],
663 },
664 {
665 apiGroups: ["ceph.rook.io"],
666 resources: ["*"],
667 verbs: ["*"],
668 },
669 ],
670 },
Sergiusz Bazanskid436de22020-02-21 17:10:42 +0100671 cmdReporter: kube.Role(cluster.name("cmd-reporter")) {
672 metadata+: cluster.metadata,
673 rules: [
674 {
675 apiGroups: [""],
676 resources: ["pods", "configmaps"],
677 verbs: ["get", "list", "watch", "create", "update", "delete"],
678 },
679 ],
680 },
Sergiusz Bazanskic6da1272019-04-02 00:06:13 +0200681 mgrSystem: kube.ClusterRole(cluster.name("mgr-system")) {
682 metadata+: cluster.metadata { namespace:: null },
683 rules: [
684 {
685 apiGroups: [""],
686 resources: ["configmaps"],
687 verbs: ["get", "list", "watch"],
688 }
689 ],
690 },
691 },
692
693 rbs: [
694 kube.RoleBinding(cluster.name(el.name)) {
695 metadata+: cluster.metadata,
Sergiusz Bazanski13bb1bf2019-08-31 16:33:29 +0200696 roleRef_: el.role,
697 subjects_: [el.sa],
Sergiusz Bazanskic6da1272019-04-02 00:06:13 +0200698 },
699 for el in [
700 // Allow Operator SA to perform Cluster Mgmt in this namespace.
Sergiusz Bazanskid436de22020-02-21 17:10:42 +0100701 { name: "cluster-mgmt", role: operator.crs.clusterMgmt, sa: operator.sa.system },
Sergiusz Bazanski13bb1bf2019-08-31 16:33:29 +0200702 { name: "osd", role: cluster.roles.osd, sa: cluster.sa.osd },
Sergiusz Bazanskic6da1272019-04-02 00:06:13 +0200703 { name: "mgr", role: cluster.roles.mgr, sa: cluster.sa.mgr },
Sergiusz Bazanskid436de22020-02-21 17:10:42 +0100704 { name: "cmd-reporter", role: cluster.roles.cmdReporter, sa: cluster.sa.cmdReporter },
Sergiusz Bazanskic6da1272019-04-02 00:06:13 +0200705 { name: "mgr-cluster", role: operator.crs.mgrCluster, sa: cluster.sa.mgr },
706 ]
707 ],
708
709 mgrSystemRB: kube.RoleBinding(cluster.name("mgr-system")) {
710 metadata+: {
711 namespace: operator.cfg.namespace,
712 },
Sergiusz Bazanski13bb1bf2019-08-31 16:33:29 +0200713 roleRef_: cluster.roles.mgrSystem,
714 subjects_: [cluster.sa.mgr],
Sergiusz Bazanskic6da1272019-04-02 00:06:13 +0200715 },
716
Serge Bazanski2c04c842021-01-19 21:41:11 +0100717 osdClusterRB: kube.ClusterRoleBinding(cluster.name("osd-cluster")) {
718 metadata+: {
719 namespace:: null,
720 },
721 roleRef_: cluster.roles.osdCluster,
722 subjects_: [cluster.sa.osd],
723 },
724
725
Sergiusz Bazanskic6da1272019-04-02 00:06:13 +0200726 cluster: kube._Object("ceph.rook.io/v1", "CephCluster", name) {
727 metadata+: cluster.metadata,
728 spec: {
729 cephVersion: {
Serge Bazanski085a8ff2021-09-12 22:08:16 +0000730 image: "quay.io/ceph/ceph:v16.2.5",
Sergiusz Bazanskied2e6702019-04-19 13:27:20 +0200731 allowUnsupported: true,
Sergiusz Bazanskic6da1272019-04-02 00:06:13 +0200732 },
Serge Bazanskic33ebcc2019-11-01 18:43:45 +0100733 dataDirHostPath: if name == "ceph-waw2" then "/var/lib/rook" else "/var/lib/rook-%s" % [name],
Sergiusz Bazanskic6da1272019-04-02 00:06:13 +0200734 dashboard: {
735 ssl: false,
736 enabled: true,
737 port: 8080,
738 },
739 } + cluster.spec,
740 },
741
742 dashboardService: kube.Service(cluster.name("dashboard")) {
743 metadata+: cluster.metadata,
744 spec: {
745 ports: [
Sergiusz Bazanski13bb1bf2019-08-31 16:33:29 +0200746 { name: "dashboard", port: 80, targetPort: 8080, protocol: "TCP" },
Sergiusz Bazanskic6da1272019-04-02 00:06:13 +0200747 ],
748 selector: {
749 app: "rook-ceph-mgr",
750 rook_cluster: name,
751 },
752 type: "ClusterIP",
753 },
754 },
755
756 dashboardIngress: kube.Ingress(cluster.name("dashboard")) {
Piotr Dobrowolski3187c592019-04-02 14:44:04 +0200757 metadata+: cluster.metadata {
758 annotations+: {
759 "kubernetes.io/tls-acme": "true",
760 "certmanager.k8s.io/cluster-issuer": "letsencrypt-prod",
761 },
762 },
Sergiusz Bazanskic6da1272019-04-02 00:06:13 +0200763 spec+: {
Piotr Dobrowolski3187c592019-04-02 14:44:04 +0200764 tls: [
765 {
766 hosts: ["%s.hswaw.net" % name],
767 secretName: cluster.name("dashboard"),
768 },
769 ],
Sergiusz Bazanskic6da1272019-04-02 00:06:13 +0200770 rules: [
771 {
772 host: "%s.hswaw.net" % name,
773 http: {
774 paths: [
775 { path: "/", backend: cluster.dashboardService.name_port },
776 ]
777 },
778 }
779 ],
780 },
Sergiusz Bazanski13bb1bf2019-08-31 16:33:29 +0200781 },
782
783 # Benji is a backup tool, external to rook, that we use for backing up
784 # RBDs.
785 benji: {
786 sa: kube.ServiceAccount(cluster.name("benji")) {
787 metadata+: cluster.metadata,
788 },
789
790 cr: kube.ClusterRole(cluster.name("benji")) {
791 rules: [
792 {
793 apiGroups: [""],
794 resources: [
795 "persistentvolumes",
796 "persistentvolumeclaims"
797 ],
798 verbs: ["list", "get"],
799 },
800 {
801 apiGroups: [""],
802 resources: [
803 "events",
804 ],
805 verbs: ["create", "update"],
806 },
807 ],
808 },
809
810 crb: kube.ClusterRoleBinding(cluster.name("benji")) {
811 roleRef_: cluster.benji.cr,
812 subjects_: [cluster.benji.sa],
813 },
814
815 config: kube.Secret(cluster.name("benji-config")) {
816 metadata+: cluster.metadata,
817 data_: {
818 "benji.yaml": std.manifestJson({
819 configurationVersion: '1',
820 databaseEngine: 'sqlite:////data/benji.sqlite',
821 defaultStorage: 'wasabi',
822 storages: [
823 {
824 name: "wasabi",
825 storageId: 1,
826 module: "s3",
827 configuration: cluster.spec.benji.s3Configuration {
828 activeTransforms: ["encrypt"],
829 },
830 },
831 ],
832 transforms: [
833 {
834 name: "encrypt",
835 module: "aes_256_gcm",
836 configuration: {
837 # not secret.
838 kdfSalt: "T2huZzZpcGhhaWM3QWVwaDhybzRhaDNhbzFpc2VpOWFobDNSZWVQaGVvTWV1bmVaYWVsNHRoYWg5QWVENHNoYWg0ZGFoN3Rlb3NvcHVuZzNpZXZpMm9vTG9vbmc1YWlmb0RlZXAwYmFobDlab294b2hjaG9odjRhbzFsYWkwYWk=",
839 kdfIterations: 2137,
840 password: cluster.spec.benji.encryptionPassword,
841 },
842 },
843 ],
844 ios: [
845 { name: pool, module: "rbd" }
846 for pool in cluster.spec.benji.pools
847 ],
848 }),
849 },
850 },
851
852 # Yes, Benji keeps data (backup metadata) on the ceph cluster that
853 # it backs up. However:
854 # - we add a command to benji-k8s to also copy over the sqlite
855 # database over to s3
856 # - benji can, in a pinch, restore without a database if a version
857 # is known: https://benji-backup.me/restore.html#restoring-without-a-database
858 data: kube.PersistentVolumeClaim(cluster.name("benji-data")) {
859 metadata+: cluster.metadata,
860 spec+: {
861 storageClassName: cluster.spec.benji.metadataStorageClass,
862 accessModes: [ "ReadWriteOnce" ],
863 resources: {
864 requests: {
865 storage: "1Gi",
866 },
867 },
868 },
869 },
870
871 # Extra scripts.
872 extrabins: kube.ConfigMap(cluster.name("benji-extrabins")) {
873 metadata+: cluster.metadata,
874 data: {
875 "metabackup.sh" : |||
876 # Make backups of sqlite3 metadata used by Benji.
877 # The backups live in the same bucket as backups, and the metabackups
878 # are named `metabackup-0..10`, where 0 is the newest backup. Any time
879 # this script is called, backups get shifted one way to the left (9 to 10,
880 # 8 to 9, etc). This ensures we have at least 10 backup replicas.
881
882 set -e
883
884 which s3cmd || pip install --upgrade s3cmd
885
886 AWS_ACCESS_KEY_ID=$(jq -r .storages[0].configuration.awsAccessKeyId < /etc/benji/benji.yaml)
887 AWS_SECRET_ACCESS_KEY=$(jq -r .storages[0].configuration.awsSecretAccessKey < /etc/benji/benji.yaml)
888 BUCKET=$(jq -r .storages[0].configuration.bucketName < /etc/benji/benji.yaml)
889
890 s3() {
891 s3cmd --host=s3.wasabisys.com \
892 "--host-bucket=%(bucket)s.s3.wasabisys.com" \
893 --region=eu-central-1 \
894 --access_key=$AWS_ACCESS_KEY_ID \
895 --secret_key=$AWS_SECRET_ACCESS_KEY \
896 "$@"
897 }
898
899 # Copy over old backups, if they exist.
900 for i in `seq 9 -1 0`; do
901 from="s3://$BUCKET/metabackup-$i.sqlite3"
902 to="s3://$BUCKET/metabackup-$((i+1)).sqlite3"
903
904 if [[ $(s3 ls $from | wc -l) -eq 0 ]]; then
905 echo "$from does not exist, skipping shift."
906 continue
907 fi
908 echo "Moving $from to $to..."
909 s3 mv $from $to
910 done
911
912 # Make new metabackup.
913 s3 put /data/benji.sqlite s3://$BUCKET/metabackup-0.sqlite3
914
915 |||,
916 "get-rook-creds.sh": |||
917 # Based on the Rook Toolbox /usr/local/bin/toolbox.sh script.
918 # Copyright 2016 The Rook Authors. All rights reserved.
919
920 CEPH_CONFIG="/etc/ceph/ceph.conf"
921 MON_CONFIG="/etc/rook/mon-endpoints"
922 KEYRING_FILE="/etc/ceph/keyring"
923
924 # create a ceph config file in its default location so ceph/rados tools can be used
925 # without specifying any arguments
926 write_endpoints() {
927 endpoints=$(cat ${MON_CONFIG})
928
929 # filter out the mon names
930 mon_endpoints=$(echo ${endpoints} | sed 's/[a-z]\+=//g')
931
932 # filter out the legacy mon names
933 mon_endpoints=$(echo ${mon_endpoints} | sed 's/rook-ceph-mon[0-9]\+=//g')
934
935 DATE=$(date)
936 echo "$DATE writing mon endpoints to ${CEPH_CONFIG}: ${endpoints}"
937 cat <<EOF > ${CEPH_CONFIG}
938 [global]
939 mon_host = ${mon_endpoints}
940
941 [client.admin]
942 keyring = ${KEYRING_FILE}
943 EOF
944 }
945
946 # watch the endpoints config file and update if the mon endpoints ever change
947 watch_endpoints() {
948 # get the timestamp for the target of the soft link
949 real_path=$(realpath ${MON_CONFIG})
950 initial_time=$(stat -c %Z ${real_path})
951 while true; do
952 real_path=$(realpath ${MON_CONFIG})
953 latest_time=$(stat -c %Z ${real_path})
954
955 if [[ "${latest_time}" != "${initial_time}" ]]; then
956 write_endpoints
957 initial_time=${latest_time}
958 fi
959 sleep 10
960 done
961 }
962
963 # create the keyring file
964 cat <<EOF > ${KEYRING_FILE}
965 [client.admin]
966 key = ${ROOK_ADMIN_SECRET}
967 EOF
968
969 # write the initial config file
970 write_endpoints
971
972 # continuously update the mon endpoints if they fail over
973 watch_endpoints &
974 |||
975 },
976 },
977
978 cronjob: kube.CronJob(cluster.name("benji")) {
979 metadata+: cluster.metadata,
980 spec+: { # CronJob Spec
Sergiusz Bazanski95868ee2019-09-26 23:47:14 +0200981 schedule: "42 0 * * *", # Daily at 42 minute past midnight.
Sergiusz Bazanski13bb1bf2019-08-31 16:33:29 +0200982 jobTemplate+: {
983 spec+: { # Job Spec
984 selector:: null,
985 template+: {
986 spec+: { # PodSpec
987 serviceAccountName: cluster.benji.sa.metadata.name,
988 containers_: {
989 benji: kube.Container(cluster.name("benji")) {
Sergiusz Bazanski0c337ac2019-12-21 23:45:07 +0100990 # TODO(q3k): switch back to upstream after pull/65 goes in.
Sergiusz Bazanski13bb1bf2019-08-31 16:33:29 +0200991 # Currently this is being built from github.com/q3k/benji.
Sergiusz Bazanski0c337ac2019-12-21 23:45:07 +0100992 # https://github.com/elemental-lf/benji/pull/65
993 image: "registry.k0.hswaw.net/q3k/benji-k8s:20191221-2336",
Sergiusz Bazanski13bb1bf2019-08-31 16:33:29 +0200994 volumeMounts_: {
995 extrabins: { mountPath: "/usr/local/extrabins" },
996 monendpoints: { mountPath: "/etc/rook" },
997 benjiconfig: { mountPath: "/etc/benji" },
998 data: { mountPath: "/data" },
999 },
1000 env_: {
1001 ROOK_ADMIN_SECRET: { secretKeyRef: { name: "rook-ceph-mon", key: "admin-secret" }},
1002 },
1003 command: [
1004 "bash", "-c", |||
1005 bash /usr/local/extrabins/get-rook-creds.sh
Sergiusz Bazanski0c337ac2019-12-21 23:45:07 +01001006 benji-backup-pvc %s
Sergiusz Bazanski13bb1bf2019-08-31 16:33:29 +02001007 benji-command enforce latest3,hours48,days7,months12
1008 benji-command cleanup
1009 bash /usr/local/extrabins/metabackup.sh
Sergiusz Bazanski0c337ac2019-12-21 23:45:07 +01001010 ||| % [std.join(" ", ["--pool-filter=%s" % [p] for p in cluster.spec.benji.pools])],
Sergiusz Bazanski13bb1bf2019-08-31 16:33:29 +02001011 ],
1012 },
1013 },
1014 volumes_: {
1015 data: kube.PersistentVolumeClaimVolume(cluster.benji.data),
1016 benjiconfig: kube.SecretVolume(cluster.benji.config),
1017 extrabins: kube.ConfigMapVolume(cluster.benji.extrabins),
1018 monendpoints: {
1019 configMap: {
1020 name: "rook-ceph-mon-endpoints",
1021 items: [
1022 { key: "data", path: "mon-endpoints" },
1023 ],
1024 },
1025 },
1026 },
1027 },
1028 },
1029 },
1030 },
1031 },
1032 },
1033 },
Sergiusz Bazanski65f3b1d2019-04-02 01:05:38 +02001034 },
1035
Sergiusz Bazanski36cc4fb2019-05-17 18:08:48 +02001036 ReplicatedBlockPool(cluster, name):: {
1037 local pool = self,
Sergiusz Bazanskid07861b2019-08-08 17:48:25 +02001038 name:: name,
1039
Sergiusz Bazanski36cc4fb2019-05-17 18:08:48 +02001040 spec:: error "spec must be specified",
1041
1042 pool: kube._Object("ceph.rook.io/v1", "CephBlockPool", name) {
1043 metadata+: cluster.metadata,
1044 spec: pool.spec,
1045 },
1046
1047 storageClass: kube.StorageClass(name) {
1048 provisioner: "ceph.rook.io/block",
1049 parameters: {
1050 blockPool: pool.pool.metadata.name,
1051 clusterNamespace: pool.pool.metadata.namespace,
1052 fstype: "ext4",
1053 },
1054 reclaimPolicy: "Retain",
1055 },
1056 },
1057
Sergiusz Bazanski65f3b1d2019-04-02 01:05:38 +02001058 ECBlockPool(cluster, name):: {
1059 local pool = self,
Sergiusz Bazanski4d61d202019-07-21 16:56:41 +02001060 name:: name,
Serge Bazanskic33ebcc2019-11-01 18:43:45 +01001061 metadataReplicas:: 3,
Sergiusz Bazanski4d61d202019-07-21 16:56:41 +02001062
Sergiusz Bazanski65f3b1d2019-04-02 01:05:38 +02001063 spec:: error "spec must be specified",
1064
1065 pool: kube._Object("ceph.rook.io/v1", "CephBlockPool", name) {
1066 metadata+: cluster.metadata,
1067 spec: pool.spec,
1068 },
1069 metapool: kube._Object("ceph.rook.io/v1", "CephBlockPool", name + "-metadata") {
1070 metadata+: cluster.metadata,
1071 spec: {
1072 failureDomain: "host",
1073 replicated: {
Serge Bazanskic33ebcc2019-11-01 18:43:45 +01001074 size: pool.metadataReplicas,
Sergiusz Bazanski65f3b1d2019-04-02 01:05:38 +02001075 },
1076 },
1077 },
1078
1079 storageClass: kube.StorageClass(name) {
1080 provisioner: "ceph.rook.io/block",
1081 parameters: {
1082 blockPool: pool.metapool.metadata.name,
1083 dataBlockPool: pool.pool.metadata.name,
1084 clusterNamespace: pool.pool.metadata.namespace,
1085 fstype: "ext4",
1086 },
1087 reclaimPolicy: "Retain",
Sergiusz Bazanskic6da1272019-04-02 00:06:13 +02001088 },
1089 },
Piotr Dobrowolski5ac85c62019-04-09 21:45:32 +02001090
Serge Bazanski38f72fe2021-09-13 23:43:47 +00001091 // This is a rook CephObjectRealm which corresponds to a radosgw realm.
1092 //
1093 // A realm is a 'world' of radosgw user-facing metadata, like credentials,
1094 // buckets, and underlying structures like zones and zonegroups. A realm
1095 // contains zonegroups and zones, but a single Ceph cluster can actually
1096 // serve multiple realms, by running multiple radosgw instances.
1097 S3ObjectRealm(cluster, name):: {
1098 cluster:: cluster,
1099 realm: kube._Object("ceph.rook.io/v1", "CephObjectRealm", name) {
Piotr Dobrowolski5ac85c62019-04-09 21:45:32 +02001100 metadata+: cluster.metadata,
Serge Bazanski38f72fe2021-09-13 23:43:47 +00001101 },
1102 },
1103
1104 // This is a rook CephObjectZoneGroup which corresponds to a radosgw
1105 // zonegroup.
1106 //
1107 // A zonegroup contains zones, and zones within a zonegroup will serve a
1108 // concise view of objects in buckets, and will sync between eachother to
1109 // eventually contain the same data.
1110 //
1111 // A single zonegroup within a realm must be a 'master' zonegroup, and will
1112 // then hold and replicate the metadata of this realm. All realm operations
1113 // via radosgw-admin must be performed within the master zonegroup.
1114 S3ObjectZoneGroup(realm, name):: {
1115 realm:: realm,
1116 zonegroup: kube._Object("ceph.rook.io/v1", "CephObjectZoneGroup", name) {
1117 metadata+: realm.cluster.metadata,
1118 spec+: {
1119 realm: realm.realm.metadata.name,
1120 },
1121 },
1122 },
1123
1124 // This is a CephObjectZone but also a CephObjectStore.
1125 //
1126 // Rook attempts to hide away Ceph's radosgw multisite structures
1127 // (realm/zonegroup/zone) by presenting a single CRD named
1128 // 'CephObjectStore'. When such a resource is created, Rook will create a
1129 // realm, zonegroup and zone under the hood, as a radosgw zone is required
1130 // to serve data, and a radosgw zone cannot exist without a zonegroup, and
1131 // a radosgw zonegroup cannot exist without a realm.
1132 //
1133 // However, rook also exposes the lower-level API by letting the user
1134 // specify 'zone' in the ObjectStore's spec, which should point to a
1135 // CephObjectZone. Then, an entirely different reconciliation codepath is
1136 // taken and instead users are expected to manage
1137 // CephObject{Realm,ZoneGroup,Zone} manually at Ceph's native abstraction
1138 // level.
1139 //
1140 // CephObjectStore not only represents a Ceph zone (and possibly
1141 // zonegroup/realm), but also pods and services that are required to servev
1142 // radosgw data publicly. That's why S3ObjectStore takes parameters like
1143 // 'public port' and 'instance number'.
1144 //
1145 // To add to the confusion, our S3ObjectStore wrapper also sprinkles in an
1146 // Ingress with TLS to terminate the above service, and automatically
1147 // creates a CephObjectZone.
1148 //
1149 // This whole jsonent abstraction basically forces users to manually create
1150 // realms and zonegroups, but makes it very easy to do so. By forcing these
1151 // to be explicitly created by rook objects, only the 'multi-site'
1152 // reconciliation codepath is taken in rook, making things a bit more
1153 // predictable.
1154 S3ObjectStore(zonegroup, name):: {
1155 local store = self,
1156 spec:: {
1157 dataPool: error "spec.dataPool must be specified",
1158 metadataPool: error "spec.metadataPool must be specified",
1159 },
1160
1161 cfg:: {
1162 // We want to have each rgw run under a domain corresponding to the
1163 // zone it's running in, but also to the zonegroup it's running in.
1164 // This will allow us to DNS loadbalance a zonegroup to be backed
1165 // by multiple zone ingresses.
1166 domainParts: [
1167 zonegroup.zone.metadata.name,
1168 zonegroup.zonegroup.metadata.name,
1169 ],
1170 domains: [
1171 "object.ceph-%s.hswaw.net" % [part]
1172 for part in cfg.domainParts
1173 ],
1174 },
1175 local cfg = self.cfg,
1176
1177 zone: kube._Object("ceph.rook.io/v1", "CephObjectZone", name) {
1178 metadata+: zonegroup.realm.cluster.metadata,
Piotr Dobrowolski5ac85c62019-04-09 21:45:32 +02001179 spec: store.spec {
Serge Bazanski38f72fe2021-09-13 23:43:47 +00001180 zoneGroup: zonegroup.zonegroup.metadata.name,
1181 },
1182 },
1183
1184 objectStore: kube._Object("ceph.rook.io/v1", "CephObjectStore", name) {
1185 metadata+: zonegroup.realm.cluster.metadata,
1186 spec: {
Piotr Dobrowolski5ac85c62019-04-09 21:45:32 +02001187 gateway: {
Piotr Dobrowolski5ac85c62019-04-09 21:45:32 +02001188 port: 80,
1189 instances: 1,
1190 allNodes: false,
1191 },
Serge Bazanski38f72fe2021-09-13 23:43:47 +00001192 zone: {
1193 name: name,
1194 },
1195 preservePoolsOnDelete: true,
Piotr Dobrowolski5ac85c62019-04-09 21:45:32 +02001196 },
1197 },
1198
1199 objectIngress: kube.Ingress(name) {
Serge Bazanski38f72fe2021-09-13 23:43:47 +00001200 metadata+: zonegroup.realm.cluster.metadata {
Piotr Dobrowolski5ac85c62019-04-09 21:45:32 +02001201 annotations+: {
1202 "kubernetes.io/tls-acme": "true",
1203 "certmanager.k8s.io/cluster-issuer": "letsencrypt-prod",
1204 "nginx.ingress.kubernetes.io/proxy-body-size": "0",
1205 },
1206 },
Serge Bazanski38f72fe2021-09-13 23:43:47 +00001207
Piotr Dobrowolski5ac85c62019-04-09 21:45:32 +02001208 spec+: {
1209 tls: [
1210 {
Serge Bazanski38f72fe2021-09-13 23:43:47 +00001211 hosts: cfg.domains,
Piotr Dobrowolski5ac85c62019-04-09 21:45:32 +02001212 secretName: "%s-tls" % [name],
1213 },
1214 ],
1215 rules: [
1216 {
Serge Bazanski38f72fe2021-09-13 23:43:47 +00001217 host: domain,
Piotr Dobrowolski5ac85c62019-04-09 21:45:32 +02001218 http: {
1219 paths: [
1220 {
1221 path: "/",
1222 backend: {
1223 serviceName: "rook-ceph-rgw-%s" % [name],
1224 servicePort: 80,
1225 },
1226 },
1227 ]
1228 },
1229 }
Serge Bazanski38f72fe2021-09-13 23:43:47 +00001230 for domain in cfg.domains
Piotr Dobrowolski5ac85c62019-04-09 21:45:32 +02001231 ],
1232 },
1233 },
1234 },
Sergiusz Bazanskib7fcc672019-04-01 18:40:50 +02001235}