blob: 8f83d2d816742f714c0e1c9539048e0a9de7049b [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:: {
Sergiusz Bazanskid436de22020-02-21 17:10:42 +010013 image: "rook/ceph:v1.1.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
Sergiusz Bazanskib7fcc672019-04-01 18:40:50 +020029 crds: {
Sergiusz Bazanskid436de22020-02-21 17:10:42 +010030 # BUG: cannot control this because of:
31 # ERROR Error updating customresourcedefinitions cephclusters.ceph.rook.io: expected kind, but got map
32 # TODO(q3k): debug and fix kubecfg (it's _not_ just https://github.com/bitnami/kubecfg/issues/259 )
33 cephclusters:: kube.CustomResourceDefinition("ceph.rook.io", "v1", "CephCluster") {
Sergiusz Bazanskib7fcc672019-04-01 18:40:50 +020034 spec+: {
35 additionalPrinterColumns: [
36 { name: "DataDirHostPath", type: "string", description: "Directory used on the K8s nodes", JSONPath: ".spec.dataDirHostPath" },
37 { name: "MonCount", type: "string", description: "Number of MONs", JSONPath: ".spec.mon.count" },
38 { name: "Age", type: "date", JSONPath: ".metadata.creationTimestamp" },
39 { name: "State", type: "string", description: "Current State", JSONPath: ".status.state" },
Sergiusz Bazanskid436de22020-02-21 17:10:42 +010040 { name: "Health", type: "string", description: "Ceaph Health", JSONPath: ".status.ceph.health" },
Sergiusz Bazanskib7fcc672019-04-01 18:40:50 +020041 ],
Sergiusz Bazanskid436de22020-02-21 17:10:42 +010042 validation: oa.Validation(oa.Dict {
43 spec: oa.Dict {
44 annotations: oa.Any,
45 cephVersion: oa.Dict {
46 allowUnsupported: oa.Boolean,
47 image: oa.String,
48 },
49 dashboard: oa.Dict {
50 enabled: oa.Boolean,
51 urlPrefix: oa.String,
52 port: oa.Integer { minimum: 0, maximum: 65535 },
53 ssl: oa.Boolean,
54 },
55 dataDirHostPath: oa.String { pattern: "^/(\\S+)" },
56 skipUpgradeChecks: oa.Boolean,
57 mon: oa.Dict {
58 allowMultiplePerNode: oa.Boolean,
59 count: oa.Integer { minimum: 0, maximum: 9 },
60 preferredCount: oa.Integer { minimum: 0, maximum: 9 },
61 },
62 mgr: oa.Dict {
63 modules: oa.Array(oa.Dict {
64 name: oa.String,
65 enabled: oa.Boolean,
66 }),
67 },
68 network: oa.Dict {
69 hostNetwork: oa.Boolean,
70 },
71 storage: oa.Dict {
72 disruptionManagement: oa.Dict {
73 managePodBudgets: oa.Boolean,
74 osdMaintenanceTimeout: oa.Integer,
75 manageMachineDisruptionBudgets: oa.Boolean,
76 },
77 useAllNodes: oa.Boolean,
78 nodes: oa.Array(oa.Dict {
79 name: oa.String,
80 config: oa.Dict {
81 metadataDevice: oa.String,
82 storeType: oa.String { pattern: "^(filestore|bluestore)$" },
83 databaseSizeMB: oa.String,
84 walSizeMB: oa.String,
85 journalSizeMB: oa.String,
86 osdsPerDevice: oa.String,
87 encryptedDevice: oa.String { pattern: "^(true|false)$" },
Sergiusz Bazanskib7fcc672019-04-01 18:40:50 +020088 },
Sergiusz Bazanskid436de22020-02-21 17:10:42 +010089 useAllDevices: oa.Boolean,
90 deviceFilter: oa.Any,
91 directories: oa.Array(oa.Dict {
92 path: oa.String,
93 }),
94 devices: oa.Array(oa.Dict {
95 name: oa.String,
96 }),
97 location: oa.Any,
98 resources: oa.Any,
99 }),
100 useAllDevices: oa.Boolean,
101 deviceFilter: oa.Any,
102 location: oa.Any,
103 directories: oa.Array(oa.Dict {
104 path: oa.String,
105 }),
106 config: oa.Any,
107 topologyAware: oa.Boolean,
108 },
109 monitoring: oa.Dict {
110 enabled: oa.Boolean,
111 rulesNamespace: oa.String,
112 },
113 rbdMirroring: oa.Dict {
114 workers: oa.Integer,
115 },
116 placement: oa.Any,
117 resources: oa.Any,
118 },
119 }),
Sergiusz Bazanskib7fcc672019-04-01 18:40:50 +0200120 },
121 },
122 cephfilesystems: kube.CustomResourceDefinition("ceph.rook.io", "v1", "CephFilesystem") {
123 spec+: {
124 additionalPrinterColumns: [
Sergiusz Bazanskid436de22020-02-21 17:10:42 +0100125 { name: "ActiveMDS", type: "string", description: "Number of desired active MDS daemons", JSONPath: ".spec.metadataServer.activeCount" },
Sergiusz Bazanskib7fcc672019-04-01 18:40:50 +0200126 { name: "Age", type: "date", JSONPath: ".metadata.creationTimestamp" },
127 ],
Sergiusz Bazanskid436de22020-02-21 17:10:42 +0100128 validation: oa.Validation(oa.Dict {
129 spec: oa.Dict {
130 metadataServer: oa.Dict {
131 activeCount: oa.Integer,
132 activeStandby: oa.Boolean,
133 annotations: oa.Any,
134 placement: oa.Any,
135 resources: oa.Any,
136 },
137 metadataPool: oa.Dict {
138 failureDomain: oa.String,
139 replicated: oa.Dict {
140 size: oa.Integer,
141 },
142 erasureCoded: oa.Dict {
143 dataChunks: oa.Integer,
144 codingChunks: oa.Integer,
145 },
146 },
147 dataPools: oa.Array(oa.Dict {
148 failureDomain: oa.String,
149 replicated: oa.Dict {
150 site: oa.Integer,
151 erasureCoded: oa.Dict {
152 dataChunks: oa.Integer,
153 codingChunks: oa.Integer,
154 },
155 },
156 })
157 },
158 }),
Sergiusz Bazanskib7fcc672019-04-01 18:40:50 +0200159 },
160 },
161 cephnfses: kube.CustomResourceDefinition("ceph.rook.io", "v1", "CephNFS") {
162 spec+: {
163 names+: {
Sergiusz Bazanskic6da1272019-04-02 00:06:13 +0200164 plural: "cephnfses",
Sergiusz Bazanskib7fcc672019-04-01 18:40:50 +0200165 shortNames: ["nfs"],
166 },
Sergiusz Bazanskid436de22020-02-21 17:10:42 +0100167 validation: oa.Validation(oa.Dict {
168 spec: oa.Dict {
169 rados: oa.Dict {
170 pool: oa.String,
171 namespace: oa.String,
172 },
173 server: oa.Dict {
174 active: oa.Integer,
175 annotations: oa.Any,
176 placement: oa.Any,
177 resources: oa.Any,
178 },
179 },
180 }),
Sergiusz Bazanskib7fcc672019-04-01 18:40:50 +0200181 },
182 },
Sergiusz Bazanskid436de22020-02-21 17:10:42 +0100183 cephobjectstores: kube.CustomResourceDefinition("ceph.rook.io", "v1", "CephObjectStore") {
184 spec+: {
185 validation: oa.Validation(oa.Dict {
186 spec: oa.Dict {
187 gateway: oa.Dict {
188 type: oa.String,
189 sslCertificateRef: oa.Any,
190 port: oa.Integer,
191 securePort: oa.Any,
192 instances: oa.Integer,
193 annotations: oa.Any,
194 placement: oa.Any,
195 resources: oa.Any,
196 },
197 local poolDef = oa.Dict {
198 failureDomain: oa.String,
199 replicated: oa.Dict {
200 size: oa.Integer,
201 },
202 erasureCoded: oa.Dict {
203 dataChunks: oa.Integer,
204 codingChunks: oa.Integer,
205 },
206 },
207 metadataPool: poolDef,
208 dataPool: poolDef,
209 },
210 }),
211 },
212 },
Sergiusz Bazanskib7fcc672019-04-01 18:40:50 +0200213 cephobjectstoreusers: kube.CustomResourceDefinition("ceph.rook.io", "v1", "CephObjectStoreUser"),
214 cephblockpools: kube.CustomResourceDefinition("ceph.rook.io", "v1", "CephBlockPool"),
215 volumes: kube.CustomResourceDefinition("rook.io", "v1alpha2", "Volume") {
216 spec+: {
217 names+: {
218 shortNames: ["rv"],
219 },
220 },
221 },
Sergiusz Bazanskid436de22020-02-21 17:10:42 +0100222 objectbuckets: kube.CustomResourceDefinition("objectbucket.io", "v1alpha1", "ObjectBucket") {
223 spec+: {
224 names+: {
225 shortNames: ["ob", "obs"],
226 },
227 scope: "Cluster",
228 subresources: { status: {} },
229 },
230 },
231 objectbucketclaims: kube.CustomResourceDefinition("objectbucket.io", "v1alpha1", "ObjectBucketClaim") {
232 spec+: {
233 names+: {
234 shortNames: ["obc", "obcs"],
235 },
236 subresources: { status: {} },
237 },
238 },
Sergiusz Bazanskib7fcc672019-04-01 18:40:50 +0200239 },
240
Sergiusz Bazanskid436de22020-02-21 17:10:42 +0100241 sa: {
242 system: kube.ServiceAccount("rook-ceph-system") {
243 metadata+: env.metadata,
244 },
245 csiCephfsPlugin: kube.ServiceAccount("rook-csi-cephfs-plugin-sa") {
246 metadata+: env.metadata,
247 },
248 csiCephfsProvisioner: kube.ServiceAccount("rook-csi-cephfs-provisioner-sa") {
249 metadata+: env.metadata,
250 },
251 csiRbdPlugin: kube.ServiceAccount("rook-csi-rbd-plugin-sa") {
252 metadata+: env.metadata,
253 },
254 csiRbdProvisioner: kube.ServiceAccount("rook-csi-rbd-provisioner-sa") {
255 metadata+: env.metadata,
256 },
Sergiusz Bazanskicdfafaf2019-04-01 19:16:18 +0200257 },
258
259 crs: {
260 clusterMgmt: kube.ClusterRole("rook-ceph-cluster-mgmt") {
Sergiusz Bazanskic6da1272019-04-02 00:06:13 +0200261 metadata+: env.metadata { namespace:: null },
Sergiusz Bazanskicdfafaf2019-04-01 19:16:18 +0200262 rules: [
263 {
264 apiGroups: [""],
265 resources: ["secrets", "pods", "pods/log", "services", "configmaps"],
266 verbs: ["get", "list", "watch", "patch", "create", "update", "delete"],
267 },
268 {
269 apiGroups: ["apps"],
270 resources: ["deployments", "daemonsets", "replicasets"],
271 verbs: ["get", "list", "watch", "create", "update", "delete"],
272 },
273 ],
274 },
275 global: kube.ClusterRole("rook-ceph-global") {
Sergiusz Bazanskic6da1272019-04-02 00:06:13 +0200276 metadata+: env.metadata { namespace:: null },
Sergiusz Bazanskicdfafaf2019-04-01 19:16:18 +0200277 rules: [
278 {
279 apiGroups: [""],
280 resources: ["pods", "nodes", "nodes/proxy"],
281 verbs: ["get", "list", "watch"],
282 },
283 {
284 apiGroups: [""],
285 resources: ["events", "persistentvolumes", "persistentvolumeclaims", "endpoints"],
286 verbs: ["get", "list", "watch", "patch", "create", "update", "delete"],
287 },
288 {
289 apiGroups: ["storage.k8s.io"],
290 resources: ["storageclasses"],
Sergiusz Bazanskid436de22020-02-21 17:10:42 +0100291 verbs: ["get", "list", "watch"],
Sergiusz Bazanskicdfafaf2019-04-01 19:16:18 +0200292 },
293 {
Sergiusz Bazanskic6da1272019-04-02 00:06:13 +0200294 apiGroups: ["batch"],
295 resources: ["jobs"],
296 verbs: ["get", "list", "watch", "create", "update", "delete"],
297 },
298 {
Sergiusz Bazanskicdfafaf2019-04-01 19:16:18 +0200299 apiGroups: ["ceph.rook.io"],
300 resources: ["*"],
301 verbs: ["*"],
302 },
303 {
304 apiGroups: ["rook.io"],
305 resources: ["*"],
306 verbs: ["*"],
307 },
Sergiusz Bazanskid436de22020-02-21 17:10:42 +0100308 {
309 apiGroups: ["policy", "apps"],
310 resources: ["poddisruptionbudgets", "deployments"],
311 verbs: ["*"],
312 },
Sergiusz Bazanskicdfafaf2019-04-01 19:16:18 +0200313 ],
314 },
Sergiusz Bazanskid436de22020-02-21 17:10:42 +0100315
316 // Upstream rook uses split ClusterRoles, with the 'main' role (eg rook-ceph-cluster-mgmt)
317 // using aggregationRules to point to a '-rules' role (eg rook-ceph-cluster-mgmt-rules) which
318 // contains the actual role rules. This was done to permit for a bettr upgrade experience on
319 // systems that only allow for a recreation of a clusterroles (see https://github.com/rook/rook/issues/2634
320 // for more background information).
321 // We do not use this split because our update mechanism is not broken. However, it seems
322 // that Rook started to use these split rules for other reasons, too. For instance, the
323 // mgr-cluster role in upstream not only aggregates its equivalent -rules role, but also
324 // the rook-ceph-object-bucket role. As such, we split mgr-cluster as they do in upstream.
325 // In the future, we may split the rest of the roles in order to stay consisdent with upsteam.
326
Sergiusz Bazanskicdfafaf2019-04-01 19:16:18 +0200327 mgrCluster: kube.ClusterRole("rook-ceph-mgr-cluster") {
Sergiusz Bazanskic6da1272019-04-02 00:06:13 +0200328 metadata+: env.metadata { namespace:: null },
Sergiusz Bazanskid436de22020-02-21 17:10:42 +0100329 aggregationRule: {
330 clusterRoleSelectors: [
331 { matchLabels: { "rbac.ceph.rook.io/aggregate-to-rook-ceph-mgr-cluster": "true" }},
332 ],
333 },
334 },
335 mgrClusterRules: kube.ClusterRole("rook-ceph-mgr-cluster-rules") {
336 metadata+: env.metadata {
337 namespace:: null,
338 labels+: {
339 "rbac.ceph.rook.io/aggregate-to-rook-ceph-mgr-cluster": "true",
340 },
341 },
Sergiusz Bazanskicdfafaf2019-04-01 19:16:18 +0200342 rules: [
343 {
344 apiGroups: [""],
345 resources: ["configmaps", "nodes", "nodes/proxy"],
346 verbs: ["get", "list", "watch"],
347 },
Sergiusz Bazanskid436de22020-02-21 17:10:42 +0100348 {
349 apiGroups: [""],
350 resources: ["events"],
351 verbs: ["create", "patch", "list", "get", "watch"],
352 },
Sergiusz Bazanskicdfafaf2019-04-01 19:16:18 +0200353 ]
354 },
Sergiusz Bazanskid436de22020-02-21 17:10:42 +0100355 objectBucket: kube.ClusterRole("rook-ceph-object-bucket") {
356 metadata+: env.metadata {
357 namespace:: null,
358 labels+: {
359 "rbac.ceph.rook.io/aggregate-to-rook-ceph-mgr-cluster": "true",
360 },
361 },
362 rules: [
363 {
364 apiGroups: [""],
365 resources: ["secrets", "configmaps"],
366 verbs: ["*"],
367 },
368 {
369 apiGroups: ["storage.k8s.io"],
370 resources: ["storageclasses"],
371 verbs: ["get", "list", "watch"],
372 },
373 {
374 apiGroups: ["objectbucket.io"],
375 resources: ["*"],
376 verbs: ["*"],
377 },
378 ],
379 },
380
381 cephfsCSINodeplugin: kube.ClusterRole("cephfs-csi-nodeplugin") {
382 metadata+: env.metadata { namespace:: null },
383 rules: [
384 {
385 apiGroups: [""],
386 resources: ["nodes"],
387 verbs: ["get", "list", "update"],
388 },
389 {
390 apiGroups: [""],
391 resources: ["namespaces"],
392 verbs: ["get", "list"],
393 },
394 {
395 apiGroups: [""],
396 resources: ["persistentvolumes"],
397 verbs: ["get", "list", "watch", "update"],
398 },
399 {
400 apiGroups: ["storage.k8s.io"],
401 resources: ["volumeattachments"],
402 verbs: ["get", "list", "watch", "update"],
403 },
404 {
405 apiGroups: [""],
406 resources: ["configmaps"],
407 verbs: ["get", "list"],
408 },
409 ],
410 },
411
412 cephfsExternalProvisionerRunner: kube.ClusterRole("cephfs-external-provisioner-runner") {
413 metadata+: env.metadata { namespace:: null },
414 rules: [
415 {
416 apiGroups: [""],
417 resources: ["secrets"],
418 verbs: ["get", "list"],
419 },
420 {
421 apiGroups: [""],
422 resources: ["persistentvolumes"],
423 verbs: ["get", "list", "watch", "create", "update", "delete"],
424 },
425 {
426 apiGroups: [""],
427 resources: ["persistentvolumeclaims"],
428 verbs: ["get", "list", "watch", "update"],
429 },
430 {
431 apiGroups: ["storage.k8s.io"],
432 resources: ["storageclasses"],
433 verbs: ["get", "list", "watch"],
434 },
435 {
436 apiGroups: [""],
437 resources: ["events"],
438 verbs: ["list", "watch", "create", "update", "patch"],
439 },
440 {
441 apiGroups: ["storage.k8s.io"],
442 resources: ["volumeattachments"],
443 verbs: ["get", "list", "watch", "update"],
444 },
445 {
446 apiGroups: [""],
447 resources: ["nodes"],
448 verbs: ["get", "list", "watch"],
449 },
450 ],
451 },
452
453 rbdCSINodeplugin: kube.ClusterRole("rbd-csi-nodeplugin") {
454 metadata+: env.metadata { namespace:: null },
455 rules: [
456 {
457 apiGroups: [""],
458 resources: ["secrets"],
459 verbs: ["get", "list"],
460 },
461 {
462 apiGroups: [""],
463 resources: ["nodes"],
464 verbs: ["get", "list", "update"],
465 },
466 {
467 apiGroups: [""],
468 resources: ["namespaces"],
469 verbs: ["get", "list"],
470 },
471 {
472 apiGroups: [""],
473 resources: ["persistentvolumes"],
474 verbs: ["get", "list", "watch", "update"],
475 },
476 {
477 apiGroups: ["storage.k8s.io"],
478 resources: ["volumeattachments"],
479 verbs: ["get", "list", "watch", "update"],
480 },
481 {
482 apiGroups: [""],
483 resources: ["configmaps"],
484 verbs: ["get", "list"],
485 },
486 ],
487 },
488
489 rbdExternalProvisionerRunner: kube.ClusterRole("rbd-external-provisioner-runner") {
490 metadata+: env.metadata { namespace:: null },
491 rules: [
492 {
493 apiGroups: [""],
494 resources: ["secrets"],
495 verbs: ["get", "list"],
496 },
497 {
498 apiGroups: [""],
499 resources: ["persistentvolumes"],
500 verbs: ["get", "list", "watch", "create", "update", "delete"],
501 },
502 {
503 apiGroups: [""],
504 resources: ["persistentvolumeclaims"],
505 verbs: ["get", "list", "watch", "update"],
506 },
507 {
508 apiGroups: ["storage.k8s.io"],
509 resources: ["volumeattachments"],
510 verbs: ["get", "list", "watch", "update"],
511 },
512 {
513 apiGroups: [""],
514 resources: ["nodes"],
515 verbs: ["get", "list", "watch"],
516 },
517 {
518 apiGroups: ["storage.k8s.io"],
519 resources: ["storageclasses"],
520 verbs: ["get", "list", "watch"]
521 },
522 {
523 apiGroups: [""],
524 resources: ["events"],
525 verbs: ["list", "watch", "create", "update", "patch"],
526 },
527 {
528 apiGroups: ["snapshot.storage.k8s.io"],
529 resources: ["volumesnapshotcontents"],
530 verbs: ["create", "get", "list", "watch", "update", "delete"],
531 },
532 {
533 apiGroups: ["snapshot.storage.k8s.io"],
534 resources: ["volumesnapshotclasses"],
535 verbs: ["get", "list", "watch"],
536 },
537 {
538 apiGroups: ["apiextensions.k8s.io"],
539 resources: ["customresourcedefinitions"],
540 verbs: ["create", "list", "watch", "delete", "get", "update"],
541 },
542 {
543 apiGroups: ["snapshot.storage.k8s.io"],
544 resources: ["volumesnapshots/status"],
545 verbs: ["update"],
546 },
547 ],
548 },
Sergiusz Bazanskicdfafaf2019-04-01 19:16:18 +0200549 },
550
Sergiusz Bazanskid436de22020-02-21 17:10:42 +0100551 crbs: {
552 global: kube.ClusterRoleBinding("ceph-rook-global") {
553 metadata+: env.metadata { namespace:: null },
554 roleRef_: env.crs.global,
555 subjects_: [env.sa.system],
556 },
557 objectBucket: kube.ClusterRoleBinding("rook-ceph-object-bucket") {
558 metadata+: env.metadata { namespace:: null },
559 roleRef_: env.crs.objectBucket,
560 subjects_: [env.sa.system],
561 },
562 cephfsCSINodeplugin: kube.ClusterRoleBinding("cepfs-csi-nodeplugin") {
563 metadata+: env.metadata { namespace:: null },
564 roleRef_: env.crs.cephfsCSINodeplugin,
565 subjects_: [env.sa.csiCephfsPlugin],
566 },
567 cephfsCSIProvisioner: kube.ClusterRoleBinding("cephfs-csi-provisioner") {
568 metadata+: env.metadata { namespace:: null },
569 roleRef_: env.crs.cephfsExternalProvisionerRunner,
570 subjects_: [env.sa.csiCephfsProvisioner],
571 },
572 rbdCSINodeplugin: kube.ClusterRoleBinding("rbd-csi-nodeplugin") {
573 metadata+: env.metadata { namespace:: null },
574 roleRef_: env.crs.rbdCSINodeplugin,
575 subjects_: [env.sa.csiRbdPlugin],
576 },
577 rbdCSIProvisioner: kube.ClusterRoleBinding("rbd-csi-provisioner") {
578 metadata+: env.metadata { namespace:: null },
579 roleRef_: env.crs.rbdExternalProvisionerRunner,
580 subjects_: [env.sa.csiRbdProvisioner],
581 },
Sergiusz Bazanskicdfafaf2019-04-01 19:16:18 +0200582 },
583
Sergiusz Bazanskid436de22020-02-21 17:10:42 +0100584 roles: {
585 system: kube.Role("ceph-rook-system") {
586 metadata+: env.metadata,
587 rules: [
588 {
589 apiGroups: [""],
590 resources: ["pods", "configmaps", "services"],
591 verbs: ["get", "list", "watch", "patch", "create", "update", "delete"],
592 },
593 {
594 apiGroups: ["apps"],
595 resources: ["deployments", "statefulsets", "daemonsets"],
596 verbs: ["get", "list", "watch", "create", "update", "delete"],
597 },
598 ],
599 },
600 cephfsExternalProvisioner: kube.Role("cephfs-external-provisioner-cfg") {
601 metadata+: env.metadata,
602 rules: [
603 {
604 apiGroups: [""],
605 resources: ["endpoints"],
606 verbs: ["get", "watch", "list", "delete", "update", "create"],
607 },
608 {
609 apiGroups: [""],
610 resources: ["configmaps"],
611 verbs: ["get", "list", "create", "delete"],
612 },
613 {
614 apiGroups: ["coordination.k8s.io"],
615 resources: ["leases"],
616 verbs: ["get" ,"watch", "list", "delete", "update", "create"],
617 },
618 ],
619 },
620 rbdExternalProvisioner: kube.Role("rbd-external-provisioner-cfg") {
621 metadata+: env.metadata,
622 rules: [
623 {
624 apiGroups: [""],
625 resources: ["endpoints"],
626 verbs: ["get", "watch", "list", "delete", "update", "create"],
627 },
628 {
629 apiGroups: [""],
630 resources: ["configmaps"],
631 verbs: ["get", "list", "watch", "create", "delete"],
632 },
633 {
634 apiGroups: ["coordination.k8s.io"],
635 resources: ["leases"],
636 verbs: ["get" ,"watch", "list", "delete", "update", "create"],
637 },
638 ],
639 },
Sergiusz Bazanskicdfafaf2019-04-01 19:16:18 +0200640 },
641
Sergiusz Bazanskid436de22020-02-21 17:10:42 +0100642 rbs: {
643 system: kube.RoleBinding("ceph-rook-system") {
644 metadata+: env.metadata,
645 roleRef_: env.roles.system,
646 subjects_: [env.sa.system],
647 },
648 cephfsCSIProvisioner: kube.RoleBinding("cephfs-csi-provisioner-role-cfg") {
649 metadata+: env.metadata,
650 roleRef_: env.roles.cephfsExternalProvisioner,
651 subjects_: [env.sa.csiCephfsProvisioner],
652 },
653 rbdCSIProvisioner: kube.RoleBinding("rbd-csi-provisioner-role-cfg") {
654 metadata+: env.metadata,
655 roleRef_: env.roles.rbdExternalProvisioner,
656 subjects_: [env.sa.csiRbdProvisioner],
657 },
Sergiusz Bazanskicdfafaf2019-04-01 19:16:18 +0200658 },
659
660 operator: kube.Deployment("rook-ceph-operator") {
661 metadata+: env.metadata,
662 spec+: {
663 template+: {
664 spec+: {
Sergiusz Bazanskid436de22020-02-21 17:10:42 +0100665 serviceAccountName: env.sa.system.metadata.name,
Sergiusz Bazanskicdfafaf2019-04-01 19:16:18 +0200666 containers_: {
667 operator: kube.Container("rook-ceph-operator") {
668 image: cfg.image,
669 args: ["ceph", "operator"],
670 volumeMounts_: {
671 "rook-config": { mountPath: "/var/lib/rook" },
672 "default-config-dir": { mountPath: "/etc/ceph" },
673 },
674 env_: {
675 LIB_MODULES_DIR_PATH: "/run/current-system/kernel-modules/lib/modules/",
676 ROOK_ALLOW_MULTIPLE_FILESYSTEMS: "false",
Sergiusz Bazanski321fad92019-04-19 14:14:36 +0200677 ROOK_LOG_LEVEL: "INFO",
Sergiusz Bazanskicdfafaf2019-04-01 19:16:18 +0200678 ROOK_MON_HEALTHCHECK_INTERVAL: "45s",
679 ROOK_MON_OUT_TIMEOUT: "600s",
680 ROOK_DISCOVER_DEVICES_INTERVAL: "60m",
681 ROOK_HOSTPATH_REQUIRES_PRIVILEGED: "false",
682 ROOK_ENABLE_SELINUX_RELABELING: "true",
683 ROOK_ENABLE_FSGROUP: "true",
684 NODE_NAME: kube.FieldRef("spec.nodeName"),
685 POD_NAME: kube.FieldRef("metadata.name"),
686 POD_NAMESPACE: kube.FieldRef("metadata.namespace"),
Sergiusz Bazanskid436de22020-02-21 17:10:42 +0100687 ROOK_CSI_KUBELET_DIR_PATH: "/var/lib/kubernetes"
Sergiusz Bazanskicdfafaf2019-04-01 19:16:18 +0200688 },
689 },
690 },
691 volumes_: {
692 "rook-config": { emptyDir: {} },
693 "default-config-dir": { emptyDir: {} },
694 },
695 },
696 },
697 },
698 },
Sergiusz Bazanskib7fcc672019-04-01 18:40:50 +0200699 },
Sergiusz Bazanskic6da1272019-04-02 00:06:13 +0200700
701 // Create a new Ceph cluster in a new namespace.
702 Cluster(operator, name):: {
703 local cluster = self,
704 spec:: error "please define cluster spec",
705
706
707 metadata:: {
708 namespace: name,
709 },
710
711 name(suffix):: cluster.metadata.namespace + "-" + suffix,
712
713 namespace: kube.Namespace(cluster.metadata.namespace),
714
715 sa: {
716 // service accounts need to be hardcoded, see operator source.
717 osd: kube.ServiceAccount("rook-ceph-osd") {
718 metadata+: cluster.metadata,
719 },
720 mgr: kube.ServiceAccount("rook-ceph-mgr") {
721 metadata+: cluster.metadata,
722 },
Sergiusz Bazanskid436de22020-02-21 17:10:42 +0100723 cmdReporter: kube.ServiceAccount("rook-ceph-cmd-reporter") {
724 metadata+: cluster.metadata,
725 },
Sergiusz Bazanskic6da1272019-04-02 00:06:13 +0200726 },
727
728 roles: {
729 osd: kube.Role(cluster.name("osd")) {
730 metadata+: cluster.metadata,
731 rules: [
732 {
733 apiGroups: [""],
734 resources: ["configmaps"],
735 verbs: ["get", "list", "watch", "create", "update", "delete"],
736 }
737 ],
738 },
739 mgr: kube.Role(cluster.name("mgr")) {
740 metadata+: cluster.metadata,
741 rules: [
742 {
743 apiGroups: [""],
744 resources: ["pods", "services"],
745 verbs: ["get", "list", "watch"],
746 },
747 {
748 apiGroups: ["batch"],
749 resources: ["jobs"],
750 verbs: ["get", "list", "watch", "create", "update", "delete"],
751 },
752 {
753 apiGroups: ["ceph.rook.io"],
754 resources: ["*"],
755 verbs: ["*"],
756 },
757 ],
758 },
Sergiusz Bazanskid436de22020-02-21 17:10:42 +0100759 cmdReporter: kube.Role(cluster.name("cmd-reporter")) {
760 metadata+: cluster.metadata,
761 rules: [
762 {
763 apiGroups: [""],
764 resources: ["pods", "configmaps"],
765 verbs: ["get", "list", "watch", "create", "update", "delete"],
766 },
767 ],
768 },
Sergiusz Bazanskic6da1272019-04-02 00:06:13 +0200769 mgrSystem: kube.ClusterRole(cluster.name("mgr-system")) {
770 metadata+: cluster.metadata { namespace:: null },
771 rules: [
772 {
773 apiGroups: [""],
774 resources: ["configmaps"],
775 verbs: ["get", "list", "watch"],
776 }
777 ],
778 },
779 },
780
781 rbs: [
782 kube.RoleBinding(cluster.name(el.name)) {
783 metadata+: cluster.metadata,
Sergiusz Bazanski13bb1bf2019-08-31 16:33:29 +0200784 roleRef_: el.role,
785 subjects_: [el.sa],
Sergiusz Bazanskic6da1272019-04-02 00:06:13 +0200786 },
787 for el in [
788 // Allow Operator SA to perform Cluster Mgmt in this namespace.
Sergiusz Bazanskid436de22020-02-21 17:10:42 +0100789 { name: "cluster-mgmt", role: operator.crs.clusterMgmt, sa: operator.sa.system },
Sergiusz Bazanski13bb1bf2019-08-31 16:33:29 +0200790 { name: "osd", role: cluster.roles.osd, sa: cluster.sa.osd },
Sergiusz Bazanskic6da1272019-04-02 00:06:13 +0200791 { name: "mgr", role: cluster.roles.mgr, sa: cluster.sa.mgr },
Sergiusz Bazanskid436de22020-02-21 17:10:42 +0100792 { name: "cmd-reporter", role: cluster.roles.cmdReporter, sa: cluster.sa.cmdReporter },
Sergiusz Bazanskic6da1272019-04-02 00:06:13 +0200793 { name: "mgr-cluster", role: operator.crs.mgrCluster, sa: cluster.sa.mgr },
794 ]
795 ],
796
797 mgrSystemRB: kube.RoleBinding(cluster.name("mgr-system")) {
798 metadata+: {
799 namespace: operator.cfg.namespace,
800 },
Sergiusz Bazanski13bb1bf2019-08-31 16:33:29 +0200801 roleRef_: cluster.roles.mgrSystem,
802 subjects_: [cluster.sa.mgr],
Sergiusz Bazanskic6da1272019-04-02 00:06:13 +0200803 },
804
805 cluster: kube._Object("ceph.rook.io/v1", "CephCluster", name) {
806 metadata+: cluster.metadata,
807 spec: {
808 cephVersion: {
Sergiusz Bazanskied2e6702019-04-19 13:27:20 +0200809 # https://github.com/rook/rook/issues/2945#issuecomment-483964014
810 #image: "ceph/ceph:v13.2.5-20190319",
Sergiusz Bazanski71a21c72019-08-30 21:30:42 +0200811 image: "ceph/ceph:v14.2.2-20190830",
Sergiusz Bazanskied2e6702019-04-19 13:27:20 +0200812 allowUnsupported: true,
Sergiusz Bazanskic6da1272019-04-02 00:06:13 +0200813 },
Serge Bazanskic33ebcc2019-11-01 18:43:45 +0100814 dataDirHostPath: if name == "ceph-waw2" then "/var/lib/rook" else "/var/lib/rook-%s" % [name],
Sergiusz Bazanskic6da1272019-04-02 00:06:13 +0200815 dashboard: {
816 ssl: false,
817 enabled: true,
818 port: 8080,
819 },
820 } + cluster.spec,
821 },
822
823 dashboardService: kube.Service(cluster.name("dashboard")) {
824 metadata+: cluster.metadata,
825 spec: {
826 ports: [
Sergiusz Bazanski13bb1bf2019-08-31 16:33:29 +0200827 { name: "dashboard", port: 80, targetPort: 8080, protocol: "TCP" },
Sergiusz Bazanskic6da1272019-04-02 00:06:13 +0200828 ],
829 selector: {
830 app: "rook-ceph-mgr",
831 rook_cluster: name,
832 },
833 type: "ClusterIP",
834 },
835 },
836
837 dashboardIngress: kube.Ingress(cluster.name("dashboard")) {
Piotr Dobrowolski3187c592019-04-02 14:44:04 +0200838 metadata+: cluster.metadata {
839 annotations+: {
840 "kubernetes.io/tls-acme": "true",
841 "certmanager.k8s.io/cluster-issuer": "letsencrypt-prod",
842 },
843 },
Sergiusz Bazanskic6da1272019-04-02 00:06:13 +0200844 spec+: {
Piotr Dobrowolski3187c592019-04-02 14:44:04 +0200845 tls: [
846 {
847 hosts: ["%s.hswaw.net" % name],
848 secretName: cluster.name("dashboard"),
849 },
850 ],
Sergiusz Bazanskic6da1272019-04-02 00:06:13 +0200851 rules: [
852 {
853 host: "%s.hswaw.net" % name,
854 http: {
855 paths: [
856 { path: "/", backend: cluster.dashboardService.name_port },
857 ]
858 },
859 }
860 ],
861 },
Sergiusz Bazanski13bb1bf2019-08-31 16:33:29 +0200862 },
863
864 # Benji is a backup tool, external to rook, that we use for backing up
865 # RBDs.
866 benji: {
867 sa: kube.ServiceAccount(cluster.name("benji")) {
868 metadata+: cluster.metadata,
869 },
870
871 cr: kube.ClusterRole(cluster.name("benji")) {
872 rules: [
873 {
874 apiGroups: [""],
875 resources: [
876 "persistentvolumes",
877 "persistentvolumeclaims"
878 ],
879 verbs: ["list", "get"],
880 },
881 {
882 apiGroups: [""],
883 resources: [
884 "events",
885 ],
886 verbs: ["create", "update"],
887 },
888 ],
889 },
890
891 crb: kube.ClusterRoleBinding(cluster.name("benji")) {
892 roleRef_: cluster.benji.cr,
893 subjects_: [cluster.benji.sa],
894 },
895
896 config: kube.Secret(cluster.name("benji-config")) {
897 metadata+: cluster.metadata,
898 data_: {
899 "benji.yaml": std.manifestJson({
900 configurationVersion: '1',
901 databaseEngine: 'sqlite:////data/benji.sqlite',
902 defaultStorage: 'wasabi',
903 storages: [
904 {
905 name: "wasabi",
906 storageId: 1,
907 module: "s3",
908 configuration: cluster.spec.benji.s3Configuration {
909 activeTransforms: ["encrypt"],
910 },
911 },
912 ],
913 transforms: [
914 {
915 name: "encrypt",
916 module: "aes_256_gcm",
917 configuration: {
918 # not secret.
919 kdfSalt: "T2huZzZpcGhhaWM3QWVwaDhybzRhaDNhbzFpc2VpOWFobDNSZWVQaGVvTWV1bmVaYWVsNHRoYWg5QWVENHNoYWg0ZGFoN3Rlb3NvcHVuZzNpZXZpMm9vTG9vbmc1YWlmb0RlZXAwYmFobDlab294b2hjaG9odjRhbzFsYWkwYWk=",
920 kdfIterations: 2137,
921 password: cluster.spec.benji.encryptionPassword,
922 },
923 },
924 ],
925 ios: [
926 { name: pool, module: "rbd" }
927 for pool in cluster.spec.benji.pools
928 ],
929 }),
930 },
931 },
932
933 # Yes, Benji keeps data (backup metadata) on the ceph cluster that
934 # it backs up. However:
935 # - we add a command to benji-k8s to also copy over the sqlite
936 # database over to s3
937 # - benji can, in a pinch, restore without a database if a version
938 # is known: https://benji-backup.me/restore.html#restoring-without-a-database
939 data: kube.PersistentVolumeClaim(cluster.name("benji-data")) {
940 metadata+: cluster.metadata,
941 spec+: {
942 storageClassName: cluster.spec.benji.metadataStorageClass,
943 accessModes: [ "ReadWriteOnce" ],
944 resources: {
945 requests: {
946 storage: "1Gi",
947 },
948 },
949 },
950 },
951
952 # Extra scripts.
953 extrabins: kube.ConfigMap(cluster.name("benji-extrabins")) {
954 metadata+: cluster.metadata,
955 data: {
956 "metabackup.sh" : |||
957 # Make backups of sqlite3 metadata used by Benji.
958 # The backups live in the same bucket as backups, and the metabackups
959 # are named `metabackup-0..10`, where 0 is the newest backup. Any time
960 # this script is called, backups get shifted one way to the left (9 to 10,
961 # 8 to 9, etc). This ensures we have at least 10 backup replicas.
962
963 set -e
964
965 which s3cmd || pip install --upgrade s3cmd
966
967 AWS_ACCESS_KEY_ID=$(jq -r .storages[0].configuration.awsAccessKeyId < /etc/benji/benji.yaml)
968 AWS_SECRET_ACCESS_KEY=$(jq -r .storages[0].configuration.awsSecretAccessKey < /etc/benji/benji.yaml)
969 BUCKET=$(jq -r .storages[0].configuration.bucketName < /etc/benji/benji.yaml)
970
971 s3() {
972 s3cmd --host=s3.wasabisys.com \
973 "--host-bucket=%(bucket)s.s3.wasabisys.com" \
974 --region=eu-central-1 \
975 --access_key=$AWS_ACCESS_KEY_ID \
976 --secret_key=$AWS_SECRET_ACCESS_KEY \
977 "$@"
978 }
979
980 # Copy over old backups, if they exist.
981 for i in `seq 9 -1 0`; do
982 from="s3://$BUCKET/metabackup-$i.sqlite3"
983 to="s3://$BUCKET/metabackup-$((i+1)).sqlite3"
984
985 if [[ $(s3 ls $from | wc -l) -eq 0 ]]; then
986 echo "$from does not exist, skipping shift."
987 continue
988 fi
989 echo "Moving $from to $to..."
990 s3 mv $from $to
991 done
992
993 # Make new metabackup.
994 s3 put /data/benji.sqlite s3://$BUCKET/metabackup-0.sqlite3
995
996 |||,
997 "get-rook-creds.sh": |||
998 # Based on the Rook Toolbox /usr/local/bin/toolbox.sh script.
999 # Copyright 2016 The Rook Authors. All rights reserved.
1000
1001 CEPH_CONFIG="/etc/ceph/ceph.conf"
1002 MON_CONFIG="/etc/rook/mon-endpoints"
1003 KEYRING_FILE="/etc/ceph/keyring"
1004
1005 # create a ceph config file in its default location so ceph/rados tools can be used
1006 # without specifying any arguments
1007 write_endpoints() {
1008 endpoints=$(cat ${MON_CONFIG})
1009
1010 # filter out the mon names
1011 mon_endpoints=$(echo ${endpoints} | sed 's/[a-z]\+=//g')
1012
1013 # filter out the legacy mon names
1014 mon_endpoints=$(echo ${mon_endpoints} | sed 's/rook-ceph-mon[0-9]\+=//g')
1015
1016 DATE=$(date)
1017 echo "$DATE writing mon endpoints to ${CEPH_CONFIG}: ${endpoints}"
1018 cat <<EOF > ${CEPH_CONFIG}
1019 [global]
1020 mon_host = ${mon_endpoints}
1021
1022 [client.admin]
1023 keyring = ${KEYRING_FILE}
1024 EOF
1025 }
1026
1027 # watch the endpoints config file and update if the mon endpoints ever change
1028 watch_endpoints() {
1029 # get the timestamp for the target of the soft link
1030 real_path=$(realpath ${MON_CONFIG})
1031 initial_time=$(stat -c %Z ${real_path})
1032 while true; do
1033 real_path=$(realpath ${MON_CONFIG})
1034 latest_time=$(stat -c %Z ${real_path})
1035
1036 if [[ "${latest_time}" != "${initial_time}" ]]; then
1037 write_endpoints
1038 initial_time=${latest_time}
1039 fi
1040 sleep 10
1041 done
1042 }
1043
1044 # create the keyring file
1045 cat <<EOF > ${KEYRING_FILE}
1046 [client.admin]
1047 key = ${ROOK_ADMIN_SECRET}
1048 EOF
1049
1050 # write the initial config file
1051 write_endpoints
1052
1053 # continuously update the mon endpoints if they fail over
1054 watch_endpoints &
1055 |||
1056 },
1057 },
1058
1059 cronjob: kube.CronJob(cluster.name("benji")) {
1060 metadata+: cluster.metadata,
1061 spec+: { # CronJob Spec
Sergiusz Bazanski95868ee2019-09-26 23:47:14 +02001062 schedule: "42 0 * * *", # Daily at 42 minute past midnight.
Sergiusz Bazanski13bb1bf2019-08-31 16:33:29 +02001063 jobTemplate+: {
1064 spec+: { # Job Spec
1065 selector:: null,
1066 template+: {
1067 spec+: { # PodSpec
1068 serviceAccountName: cluster.benji.sa.metadata.name,
1069 containers_: {
1070 benji: kube.Container(cluster.name("benji")) {
Sergiusz Bazanski0c337ac2019-12-21 23:45:07 +01001071 # TODO(q3k): switch back to upstream after pull/65 goes in.
Sergiusz Bazanski13bb1bf2019-08-31 16:33:29 +02001072 # Currently this is being built from github.com/q3k/benji.
Sergiusz Bazanski0c337ac2019-12-21 23:45:07 +01001073 # https://github.com/elemental-lf/benji/pull/65
1074 image: "registry.k0.hswaw.net/q3k/benji-k8s:20191221-2336",
Sergiusz Bazanski13bb1bf2019-08-31 16:33:29 +02001075 volumeMounts_: {
1076 extrabins: { mountPath: "/usr/local/extrabins" },
1077 monendpoints: { mountPath: "/etc/rook" },
1078 benjiconfig: { mountPath: "/etc/benji" },
1079 data: { mountPath: "/data" },
1080 },
1081 env_: {
1082 ROOK_ADMIN_SECRET: { secretKeyRef: { name: "rook-ceph-mon", key: "admin-secret" }},
1083 },
1084 command: [
1085 "bash", "-c", |||
1086 bash /usr/local/extrabins/get-rook-creds.sh
Sergiusz Bazanski0c337ac2019-12-21 23:45:07 +01001087 benji-backup-pvc %s
Sergiusz Bazanski13bb1bf2019-08-31 16:33:29 +02001088 benji-command enforce latest3,hours48,days7,months12
1089 benji-command cleanup
1090 bash /usr/local/extrabins/metabackup.sh
Sergiusz Bazanski0c337ac2019-12-21 23:45:07 +01001091 ||| % [std.join(" ", ["--pool-filter=%s" % [p] for p in cluster.spec.benji.pools])],
Sergiusz Bazanski13bb1bf2019-08-31 16:33:29 +02001092 ],
1093 },
1094 },
1095 volumes_: {
1096 data: kube.PersistentVolumeClaimVolume(cluster.benji.data),
1097 benjiconfig: kube.SecretVolume(cluster.benji.config),
1098 extrabins: kube.ConfigMapVolume(cluster.benji.extrabins),
1099 monendpoints: {
1100 configMap: {
1101 name: "rook-ceph-mon-endpoints",
1102 items: [
1103 { key: "data", path: "mon-endpoints" },
1104 ],
1105 },
1106 },
1107 },
1108 },
1109 },
1110 },
1111 },
1112 },
1113 },
1114 },
Sergiusz Bazanski65f3b1d2019-04-02 01:05:38 +02001115 },
1116
Sergiusz Bazanski36cc4fb2019-05-17 18:08:48 +02001117 ReplicatedBlockPool(cluster, name):: {
1118 local pool = self,
Sergiusz Bazanskid07861b2019-08-08 17:48:25 +02001119 name:: name,
1120
Sergiusz Bazanski36cc4fb2019-05-17 18:08:48 +02001121 spec:: error "spec must be specified",
1122
1123 pool: kube._Object("ceph.rook.io/v1", "CephBlockPool", name) {
1124 metadata+: cluster.metadata,
1125 spec: pool.spec,
1126 },
1127
1128 storageClass: kube.StorageClass(name) {
1129 provisioner: "ceph.rook.io/block",
1130 parameters: {
1131 blockPool: pool.pool.metadata.name,
1132 clusterNamespace: pool.pool.metadata.namespace,
1133 fstype: "ext4",
1134 },
1135 reclaimPolicy: "Retain",
1136 },
1137 },
1138
Sergiusz Bazanski65f3b1d2019-04-02 01:05:38 +02001139 ECBlockPool(cluster, name):: {
1140 local pool = self,
Sergiusz Bazanski4d61d202019-07-21 16:56:41 +02001141 name:: name,
Serge Bazanskic33ebcc2019-11-01 18:43:45 +01001142 metadataReplicas:: 3,
Sergiusz Bazanski4d61d202019-07-21 16:56:41 +02001143
Sergiusz Bazanski65f3b1d2019-04-02 01:05:38 +02001144 spec:: error "spec must be specified",
1145
1146 pool: kube._Object("ceph.rook.io/v1", "CephBlockPool", name) {
1147 metadata+: cluster.metadata,
1148 spec: pool.spec,
1149 },
1150 metapool: kube._Object("ceph.rook.io/v1", "CephBlockPool", name + "-metadata") {
1151 metadata+: cluster.metadata,
1152 spec: {
1153 failureDomain: "host",
1154 replicated: {
Serge Bazanskic33ebcc2019-11-01 18:43:45 +01001155 size: pool.metadataReplicas,
Sergiusz Bazanski65f3b1d2019-04-02 01:05:38 +02001156 },
1157 },
1158 },
1159
1160 storageClass: kube.StorageClass(name) {
1161 provisioner: "ceph.rook.io/block",
1162 parameters: {
1163 blockPool: pool.metapool.metadata.name,
1164 dataBlockPool: pool.pool.metadata.name,
1165 clusterNamespace: pool.pool.metadata.namespace,
1166 fstype: "ext4",
1167 },
1168 reclaimPolicy: "Retain",
Sergiusz Bazanskic6da1272019-04-02 00:06:13 +02001169 },
1170 },
Piotr Dobrowolski5ac85c62019-04-09 21:45:32 +02001171
1172 S3ObjectStore(cluster, name):: {
1173 local store = self,
1174 spec:: error "spec must be specified",
1175 objectStore: kube._Object("ceph.rook.io/v1", "CephObjectStore", name) {
1176 metadata+: cluster.metadata,
1177 spec: store.spec {
1178 gateway: {
1179 type: "s3",
1180 port: 80,
1181 instances: 1,
1182 allNodes: false,
1183 },
1184 },
1185 },
1186
1187 objectIngress: kube.Ingress(name) {
1188 metadata+: cluster.metadata {
1189 annotations+: {
1190 "kubernetes.io/tls-acme": "true",
1191 "certmanager.k8s.io/cluster-issuer": "letsencrypt-prod",
1192 "nginx.ingress.kubernetes.io/proxy-body-size": "0",
1193 },
1194 },
1195 spec+: {
1196 tls: [
1197 {
1198 hosts: ["object.%s.hswaw.net" % [cluster.metadata.namespace]],
1199 secretName: "%s-tls" % [name],
1200 },
1201 ],
1202 rules: [
1203 {
1204 host: "object.%s.hswaw.net" % [cluster.metadata.namespace],
1205 http: {
1206 paths: [
1207 {
1208 path: "/",
1209 backend: {
1210 serviceName: "rook-ceph-rgw-%s" % [name],
1211 servicePort: 80,
1212 },
1213 },
1214 ]
1215 },
1216 }
1217 ],
1218 },
1219 },
1220 },
Sergiusz Bazanskib7fcc672019-04-01 18:40:50 +02001221}