diff --git a/cue.mod/gen/github.com/rook/rook/pkg/apis/ceph.rook.io/BUILD.bazel b/cue.mod/gen/github.com/rook/rook/pkg/apis/ceph.rook.io/BUILD.bazel new file mode 100644 index 000000000..c1cd37e4f --- /dev/null +++ b/cue.mod/gen/github.com/rook/rook/pkg/apis/ceph.rook.io/BUILD.bazel @@ -0,0 +1,8 @@ +load("@com_github_tnarg_rules_cue//cue:cue.bzl", "cue_library") + +cue_library( + name = "cue_cephrookio_library", + srcs = ["register_go_gen.cue"], + importpath = "github.com/rook/rook/pkg/apis/ceph.rook.io:cephrookio", + visibility = ["//visibility:public"], +) diff --git a/cue.mod/gen/time/BUILD.bazel b/cue.mod/gen/time/BUILD.bazel new file mode 100644 index 000000000..0c3377702 --- /dev/null +++ b/cue.mod/gen/time/BUILD.bazel @@ -0,0 +1,13 @@ +load("@com_github_tnarg_rules_cue//cue:cue.bzl", "cue_library") + +cue_library( + name = "cue_time_library", + srcs = [ + "format_go_gen.cue", + "time_go_gen.cue", + "zoneinfo_go_gen.cue", + "zoneinfo_read_go_gen.cue", + ], + importpath = "github.com/uhthomas/automata/cue.mod/gen/time", + visibility = ["//visibility:public"], +) diff --git a/k8s/amour/BUILD.bazel b/k8s/amour/BUILD.bazel index f72786d28..aada0b595 100644 --- a/k8s/amour/BUILD.bazel +++ b/k8s/amour/BUILD.bazel @@ -40,6 +40,7 @@ cue_export( "//k8s/amour/nvidia_device_plugin:cue_nvidia_device_plugin_library", "//k8s/amour/onepassword_connect:cue_onepassword_connect_library", "//k8s/amour/rook_ceph:cue_rook_ceph_library", + "//k8s/amour/scrutiny:cue_scrutiny_library", "//k8s/amour/smartctl_exporter:cue_smartctl_exporter_library", "//k8s/amour/snapshot_controller:cue_snapshot_controller_library", "//k8s/amour/tailscale:cue_tailscale_library", diff --git a/k8s/amour/list.cue b/k8s/amour/list.cue index 1bcd1afff..efeae127f 100644 --- a/k8s/amour/list.cue +++ b/k8s/amour/list.cue @@ -20,6 +20,7 @@ import ( "github.com/uhthomas/automata/k8s/amour/nvidia_device_plugin" "github.com/uhthomas/automata/k8s/amour/onepassword_connect" "github.com/uhthomas/automata/k8s/amour/rook_ceph" + "github.com/uhthomas/automata/k8s/amour/scrutiny" "github.com/uhthomas/automata/k8s/amour/smartctl_exporter" "github.com/uhthomas/automata/k8s/amour/snapshot_controller" "github.com/uhthomas/automata/k8s/amour/tailscale" @@ -71,6 +72,7 @@ _items: [ nvidia_device_plugin.#List.items, onepassword_connect.#List.items, rook_ceph.#List.items, + scrutiny.#List.items, smartctl_exporter.#List.items, snapshot_controller.#List.items, tailscale.#List.items, diff --git a/k8s/amour/scrutiny/BUILD.bazel b/k8s/amour/scrutiny/BUILD.bazel new file mode 100644 index 000000000..961666d89 --- /dev/null +++ b/k8s/amour/scrutiny/BUILD.bazel @@ -0,0 +1,17 @@ +load("@com_github_tnarg_rules_cue//cue:cue.bzl", "cue_library") + +cue_library( + name = "cue_scrutiny_library", + srcs = [ + "list.cue", + "namespace_list.cue", + ], + importpath = "github.com/uhthomas/automata/k8s/amour/scrutiny", + visibility = ["//visibility:public"], + deps = [ + "//cue.mod/gen/k8s.io/api/core/v1:cue_v1_library", + "//k8s/amour/scrutiny/collector:cue_collector_library", + "//k8s/amour/scrutiny/influxdb:cue_influxdb_library", + "//k8s/amour/scrutiny/web:cue_web_library", + ], +) diff --git a/k8s/amour/scrutiny/README.md b/k8s/amour/scrutiny/README.md new file mode 100644 index 000000000..3a6b040c5 --- /dev/null +++ b/k8s/amour/scrutiny/README.md @@ -0,0 +1,5 @@ +# scrutiny + +[https://github.com/AnalogJ/scrutiny](https://github.com/AnalogJ/scrutiny) + +Some inspiration from [this PR](https://github.com/AnalogJ/scrutiny/pull/363). diff --git a/k8s/amour/scrutiny/collector/BUILD.bazel b/k8s/amour/scrutiny/collector/BUILD.bazel new file mode 100644 index 000000000..40ba9c451 --- /dev/null +++ b/k8s/amour/scrutiny/collector/BUILD.bazel @@ -0,0 +1,16 @@ +load("@com_github_tnarg_rules_cue//cue:cue.bzl", "cue_library") + +cue_library( + name = "cue_collector_library", + srcs = [ + "daemon_set_list.cue", + "list.cue", + "service_account_list.cue", + ], + importpath = "github.com/uhthomas/automata/k8s/amour/scrutiny/collector", + visibility = ["//visibility:public"], + deps = [ + "//cue.mod/gen/k8s.io/api/apps/v1:cue_v1_library", + "//cue.mod/gen/k8s.io/api/core/v1:cue_v1_library", + ], +) diff --git a/k8s/amour/scrutiny/collector/daemon_set_list.cue b/k8s/amour/scrutiny/collector/daemon_set_list.cue new file mode 100644 index 000000000..2ededaa34 --- /dev/null +++ b/k8s/amour/scrutiny/collector/daemon_set_list.cue @@ -0,0 +1,69 @@ +package collector + +import ( + appsv1 "k8s.io/api/apps/v1" + "k8s.io/api/core/v1" +) + +#DaemonSetList: appsv1.#DaemonSetList & { + apiVersion: "apps/v1" + kind: "DaemonSetList" + items: [...{ + apiVersion: "apps/v1" + kind: "DaemonSet" + }] +} + +#DaemonSetList: items: [{ + spec: { + selector: matchLabels: "app.kubernetes.io/name": #Name + template: { + metadata: labels: "app.kubernetes.io/name": #Name + spec: { + volumes: [{ + name: "udev" + hostPath: path: "/run/udev" + }] + containers: [{ + name: "collector" + image: "ghcr.io/analogj/scrutiny:v\(#Version)-collector" + env: [{ + name: "COLLECTOR_API_ENDPOINT" + value: "http://scrutiny-web" + }, { + name: "COLLECTOR_RUN_STARTUP" + value: "true" + }] + resources: limits: { + (v1.#ResourceCPU): "100m" + (v1.#ResourceMemory): "32Mi" + } + volumeMounts: [{ + name: "udev" + mountPath: "/run/udev" + readOnly: true + }] + imagePullPolicy: v1.#PullIfNotPresent + securityContext: { + capabilities: { + add: ["SYS_ADMIN", "SYS_RAWIO"] + drop: ["ALL"] + } + privileged: true + // readOnlyRootFilesystem: true + // allowPrivilegeEscalation: false + } + + }] + serviceAccountName: #Name + // securityContext: { + // runAsUser: 1000 + // runAsGroup: 3000 + // runAsNonRoot: true + // fsGroup: 2000 + // seccompProfile: type: v1.#SeccompProfileTypeRuntimeDefault + // } + } + } + } +}] diff --git a/k8s/amour/scrutiny/collector/list.cue b/k8s/amour/scrutiny/collector/list.cue new file mode 100644 index 000000000..90f82e0b1 --- /dev/null +++ b/k8s/amour/scrutiny/collector/list.cue @@ -0,0 +1,32 @@ +package collector + +import ( + "list" + + "k8s.io/api/core/v1" +) + +#Name: "scrutiny-collector" +#Namespace: "scrutiny" +#Version: "0.7.2" + +#List: v1.#List & { + apiVersion: "v1" + kind: "List" + items: [...{ + metadata: { + name: #Name + labels: { + "app.kubernetes.io/name": #Name + "app.kubernetes.io/version": #Version + } + } + }] +} + +#List: items: list.Concat(_items) + +_items: [ + #DaemonSetList.items, + #ServiceAccountList.items, +] diff --git a/k8s/amour/scrutiny/collector/service_account_list.cue b/k8s/amour/scrutiny/collector/service_account_list.cue new file mode 100644 index 000000000..2b658d4f1 --- /dev/null +++ b/k8s/amour/scrutiny/collector/service_account_list.cue @@ -0,0 +1,14 @@ +package collector + +import "k8s.io/api/core/v1" + +#ServiceAccountList: v1.#ServiceAccountList & { + apiVersion: "v1" + kind: "ServiceAccountList" + items: [...{ + apiVersion: "v1" + kind: "ServiceAccount" + }] +} + +#ServiceAccountList: items: [{}] diff --git a/k8s/amour/scrutiny/influxdb/BUILD.bazel b/k8s/amour/scrutiny/influxdb/BUILD.bazel new file mode 100644 index 000000000..8d41720e3 --- /dev/null +++ b/k8s/amour/scrutiny/influxdb/BUILD.bazel @@ -0,0 +1,18 @@ +load("@com_github_tnarg_rules_cue//cue:cue.bzl", "cue_library") + +cue_library( + name = "cue_influxdb_library", + srcs = [ + "external_secret_list.cue", + "list.cue", + "service_list.cue", + "stateful_set_list.cue", + ], + importpath = "github.com/uhthomas/automata/k8s/amour/scrutiny/influxdb", + visibility = ["//visibility:public"], + deps = [ + "//cue.mod/gen/github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1:cue_v1beta1_library", + "//cue.mod/gen/k8s.io/api/apps/v1:cue_v1_library", + "//cue.mod/gen/k8s.io/api/core/v1:cue_v1_library", + ], +) diff --git a/k8s/amour/scrutiny/influxdb/README.md b/k8s/amour/scrutiny/influxdb/README.md new file mode 100644 index 000000000..a5c3a3e87 --- /dev/null +++ b/k8s/amour/scrutiny/influxdb/README.md @@ -0,0 +1,5 @@ +# influxdb + +[https://github.com/influxdata/influxdb](https://github.com/influxdata/influxdb) + +Some inspiration from the [official Helm chart](https://github.com/influxdata/helm-charts/tree/5da1bad7153326bbd0ed09f1ecdcde519d2be07d/charts/influxdb2). diff --git a/k8s/amour/scrutiny/influxdb/external_secret_list.cue b/k8s/amour/scrutiny/influxdb/external_secret_list.cue new file mode 100644 index 000000000..7def87bbe --- /dev/null +++ b/k8s/amour/scrutiny/influxdb/external_secret_list.cue @@ -0,0 +1,41 @@ +package influxdb + +import externalsecretsv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1" + +#ExternalSecretList: externalsecretsv1beta1.#ExternalSecretList & { + apiVersion: "external-secrets.io/v1beta1" + kind: "ExternalSecretList" + items: [...{ + apiVersion: "external-secrets.io/v1beta1" + kind: "ExternalSecret" + }] +} + +#ExternalSecretList: items: [{ + spec: { + secretStoreRef: { + name: "onepassword" + kind: "ClusterSecretStore" + } + target: template: metadata: { + annotations: {} + labels: {} + } + dataFrom: [{ + extract: { + key: "scrutiny-influxdb" + property: "username" + } + }, { + extract: { + key: "scrutiny-influxdb" + property: "password" + } + }, { + extract: { + key: "scrutiny-influxdb" + property: "token" + } + }] + } +}] diff --git a/k8s/amour/scrutiny/influxdb/list.cue b/k8s/amour/scrutiny/influxdb/list.cue new file mode 100644 index 000000000..b27fbcd2c --- /dev/null +++ b/k8s/amour/scrutiny/influxdb/list.cue @@ -0,0 +1,33 @@ +package influxdb + +import ( + "list" + + "k8s.io/api/core/v1" +) + +#Name: "scrutiny-influxdb" +#Namespace: "scrutiny" +#Version: "2.7.4" + +#List: v1.#List & { + apiVersion: "v1" + kind: "List" + items: [...{ + metadata: { + name: #Name + labels: { + "app.kubernetes.io/name": #Name + "app.kubernetes.io/version": #Version + } + } + }] +} + +#List: items: list.Concat(_items) + +_items: [ + #ExternalSecretList.items, + #ServiceList.items, + #StatefulSetList.items, +] diff --git a/k8s/amour/scrutiny/influxdb/service_list.cue b/k8s/amour/scrutiny/influxdb/service_list.cue new file mode 100644 index 000000000..6d2254911 --- /dev/null +++ b/k8s/amour/scrutiny/influxdb/service_list.cue @@ -0,0 +1,23 @@ +package influxdb + +import "k8s.io/api/core/v1" + +#ServiceList: v1.#ServiceList & { + apiVersion: "v1" + kind: "ServiceList" + items: [...{ + apiVersion: "v1" + kind: "Service" + }] +} + +#ServiceList: items: [{ + spec: { + ports: [{ + name: "http" + port: 8086 + targetPort: "http" + }] + selector: "app.kubernetes.io/name": #Name + } +}] diff --git a/k8s/amour/scrutiny/influxdb/stateful_set_list.cue b/k8s/amour/scrutiny/influxdb/stateful_set_list.cue new file mode 100644 index 000000000..42c7ffa7c --- /dev/null +++ b/k8s/amour/scrutiny/influxdb/stateful_set_list.cue @@ -0,0 +1,119 @@ +package influxdb + +import ( + appsv1 "k8s.io/api/apps/v1" + "k8s.io/api/core/v1" +) + +#StatefulSetList: appsv1.#StatefulSetList & { + apiVersion: "apps/v1" + kind: "StatefulSetList" + items: [...{ + apiVersion: "apps/v1" + kind: "StatefulSet" + }] +} + +#StatefulSetList: items: [{ + spec: { + selector: matchLabels: "app.kubernetes.io/name": #Name + template: { + metadata: labels: "app.kubernetes.io/name": #Name + spec: { + volumes: [{ + name: "tmp" + emptyDir: {} + }] + containers: [{ + name: "influxdb" + image: "influxdb:\(#Version)-alpine" + ports: [{ + name: "http" + containerPort: 8086 + }] + env: [{ + name: "DOCKER_INFLUXDB_INIT_MODE" + value: "setup" + }, { + name: "DOCKER_INFLUXDB_INIT_USERNAME" + valueFrom: secretKeyRef: { + name: #Name + key: "username" + } + }, { + name: "DOCKER_INFLUXDB_INIT_PASSWORD" + valueFrom: secretKeyRef: { + name: #Name + key: "password" + } + }, { + name: "DOCKER_INFLUXDB_INIT_ORG" + value: "scrutiny" + }, { + name: "DOCKER_INFLUXDB_INIT_BUCKET" + value: "default" + }, { + name: "DOCKER_INFLUXDB_INIT_RETENTION" + value: "0s" + }, { + name: "DOCKER_INFLUXDB_INIT_ADMIN_TOKEN" + valueFrom: secretKeyRef: { + name: #Name + key: "token" + } + }, { + name: "INFLUXD_BOLT_PATH" + value: "/var/lib/influxdb2/influxd.bolt" + }, { + name: "INFLUXD_ENGINE_PATH" + value: "/var/lib/influxdb2" + }] + resources: limits: { + (v1.#ResourceCPU): "150m" + (v1.#ResourceMemory): "128Mi" + } + volumeMounts: [{ + name: "tmp" + mountPath: "/tmp" + }, { + name: "data" + mountPath: "/var/lib/influxdb2" + }] + + let probe = { + httpGet: { + path: "/health" + port: "http" + } + } + + livenessProbe: probe + readinessProbe: probe + + imagePullPolicy: v1.#PullIfNotPresent + securityContext: { + capabilities: drop: ["ALL"] + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + } + }] + securityContext: { + runAsUser: 1000 + runAsGroup: 3000 + runAsNonRoot: true + fsGroup: 2000 + seccompProfile: type: v1.#SeccompProfileTypeRuntimeDefault + } + } + } + volumeClaimTemplates: [{ + metadata: name: "data" + spec: { + accessModes: [v1.#ReadWriteOnce] + storageClassName: "rook-ceph-nvme" + resources: requests: (v1.#ResourceStorage): "1Gi" + } + }] + serviceName: #Name + } +}] diff --git a/k8s/amour/scrutiny/list.cue b/k8s/amour/scrutiny/list.cue new file mode 100644 index 000000000..31094f6d1 --- /dev/null +++ b/k8s/amour/scrutiny/list.cue @@ -0,0 +1,33 @@ +package scrutiny + +import ( + "list" + + "github.com/uhthomas/automata/k8s/amour/scrutiny/collector" + "github.com/uhthomas/automata/k8s/amour/scrutiny/influxdb" + "github.com/uhthomas/automata/k8s/amour/scrutiny/web" + "k8s.io/api/core/v1" +) + +#Name: "scrutiny" +#Namespace: #Name + +#List: v1.#List & { + apiVersion: "v1" + kind: "List" + items: [...{ + metadata: { + name: string | *#Name + namespace: #Namespace + } + }] +} + +#List: items: list.Concat(_items) + +_items: [ + #NamespaceList.items, + collector.#List.items, + influxdb.#List.items, + web.#List.items, +] diff --git a/k8s/amour/scrutiny/namespace_list.cue b/k8s/amour/scrutiny/namespace_list.cue new file mode 100644 index 000000000..27d460b53 --- /dev/null +++ b/k8s/amour/scrutiny/namespace_list.cue @@ -0,0 +1,14 @@ +package scrutiny + +import "k8s.io/api/core/v1" + +#NamespaceList: v1.#NamespaceList & { + apiVersion: "v1" + kind: "NamespaceList" + items: [...{ + apiVersion: "v1" + kind: "Namespace" + }] +} + +#NamespaceList: items: [{metadata: labels: "pod-security.kubernetes.io/enforce": "privileged"}] diff --git a/k8s/amour/scrutiny/web/BUILD.bazel b/k8s/amour/scrutiny/web/BUILD.bazel new file mode 100644 index 000000000..599348829 --- /dev/null +++ b/k8s/amour/scrutiny/web/BUILD.bazel @@ -0,0 +1,20 @@ +load("@com_github_tnarg_rules_cue//cue:cue.bzl", "cue_library") + +cue_library( + name = "cue_web_library", + srcs = [ + "external_secret_list.cue", + "ingress_list.cue", + "list.cue", + "service_list.cue", + "stateful_set_list.cue", + ], + importpath = "github.com/uhthomas/automata/k8s/amour/scrutiny/web", + visibility = ["//visibility:public"], + deps = [ + "//cue.mod/gen/github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1:cue_v1beta1_library", + "//cue.mod/gen/k8s.io/api/apps/v1:cue_v1_library", + "//cue.mod/gen/k8s.io/api/core/v1:cue_v1_library", + "//cue.mod/gen/k8s.io/api/networking/v1:cue_v1_library", + ], +) diff --git a/k8s/amour/scrutiny/web/external_secret_list.cue b/k8s/amour/scrutiny/web/external_secret_list.cue new file mode 100644 index 000000000..f655defb4 --- /dev/null +++ b/k8s/amour/scrutiny/web/external_secret_list.cue @@ -0,0 +1,31 @@ +package web + +import externalsecretsv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1" + +#ExternalSecretList: externalsecretsv1beta1.#ExternalSecretList & { + apiVersion: "external-secrets.io/v1beta1" + kind: "ExternalSecretList" + items: [...{ + apiVersion: "external-secrets.io/v1beta1" + kind: "ExternalSecret" + }] +} + +#ExternalSecretList: items: [{ + spec: { + secretStoreRef: { + name: "onepassword" + kind: "ClusterSecretStore" + } + target: template: metadata: { + annotations: {} + labels: {} + } + dataFrom: [{ + extract: { + key: "scrutiny-influxdb" + property: "token" + } + }] + } +}] diff --git a/k8s/amour/scrutiny/web/ingress_list.cue b/k8s/amour/scrutiny/web/ingress_list.cue new file mode 100644 index 000000000..c13271c2c --- /dev/null +++ b/k8s/amour/scrutiny/web/ingress_list.cue @@ -0,0 +1,23 @@ +package web + +import networkingv1 "k8s.io/api/networking/v1" + +#IngressList: networkingv1.#IngressList & { + apiVersion: "networking.k8s.io/v1" + kind: "IngressList" + items: [...{ + apiVersion: "networking.k8s.io/v1" + kind: "Ingress" + }] +} + +#IngressList: items: [{ + spec: { + ingressClassName: "tailscale" + defaultBackend: service: { + name: #Name + port: name: "http" + } + tls: [{hosts: ["\(#Name)-amour-k8s"]}] + } +}] diff --git a/k8s/amour/scrutiny/web/list.cue b/k8s/amour/scrutiny/web/list.cue new file mode 100644 index 000000000..dd0c6e841 --- /dev/null +++ b/k8s/amour/scrutiny/web/list.cue @@ -0,0 +1,34 @@ +package web + +import ( + "list" + + "k8s.io/api/core/v1" +) + +#Name: "scrutiny-web" +#Namespace: "scrutiny" +#Version: "0.7.2" + +#List: v1.#List & { + apiVersion: "v1" + kind: "List" + items: [...{ + metadata: { + name: #Name + labels: { + "app.kubernetes.io/name": #Name + "app.kubernetes.io/version": #Version + } + } + }] +} + +#List: items: list.Concat(_items) + +_items: [ + #ExternalSecretList.items, + #IngressList.items, + #ServiceList.items, + #StatefulSetList.items, +] diff --git a/k8s/amour/scrutiny/web/service_list.cue b/k8s/amour/scrutiny/web/service_list.cue new file mode 100644 index 000000000..7b633fa98 --- /dev/null +++ b/k8s/amour/scrutiny/web/service_list.cue @@ -0,0 +1,23 @@ +package web + +import "k8s.io/api/core/v1" + +#ServiceList: v1.#ServiceList & { + apiVersion: "v1" + kind: "ServiceList" + items: [...{ + apiVersion: "v1" + kind: "Service" + }] +} + +#ServiceList: items: [{ + spec: { + ports: [{ + name: "http" + port: 80 + targetPort: "http" + }] + selector: "app.kubernetes.io/name": #Name + } +}] diff --git a/k8s/amour/scrutiny/web/stateful_set_list.cue b/k8s/amour/scrutiny/web/stateful_set_list.cue new file mode 100644 index 000000000..38b9c350d --- /dev/null +++ b/k8s/amour/scrutiny/web/stateful_set_list.cue @@ -0,0 +1,85 @@ +package web + +import ( + appsv1 "k8s.io/api/apps/v1" + "k8s.io/api/core/v1" +) + +#StatefulSetList: appsv1.#StatefulSetList & { + apiVersion: "apps/v1" + kind: "StatefulSetList" + items: [...{ + apiVersion: "apps/v1" + kind: "StatefulSet" + }] +} + +#StatefulSetList: items: [{ + spec: { + selector: matchLabels: "app.kubernetes.io/name": #Name + template: { + metadata: labels: "app.kubernetes.io/name": #Name + spec: { + containers: [{ + name: "web" + image: "ghcr.io/analogj/scrutiny:v\(#Version)-web" + ports: [{ + name: "http" + containerPort: 8080 + }] + env: [{ + name: "SCRUTINY_WEB_INFLUXDB_HOST" + value: "scrutiny-influxdb" + }, { + name: "SCRUTINY_WEB_INFLUXDB_TOKEN" + valueFrom: secretKeyRef: { + name: #Name + key: "token" + } + }] + resources: limits: { + (v1.#ResourceCPU): "100m" + (v1.#ResourceMemory): "32Mi" + } + volumeMounts: [{ + name: "data" + mountPath: "/opt/scrutiny/config" + }] + + let probe = { + httpGet: { + path: "/health" + port: "http" + } + } + + livenessProbe: probe + readinessProbe: probe + + imagePullPolicy: v1.#PullIfNotPresent + securityContext: { + capabilities: drop: ["ALL"] + readOnlyRootFilesystem: true + allowPrivilegeEscalation: false + } + }] + securityContext: { + runAsUser: 1000 + runAsGroup: 3000 + runAsNonRoot: true + fsGroup: 2000 + seccompProfile: type: v1.#SeccompProfileTypeRuntimeDefault + } + } + } + volumeClaimTemplates: [{ + metadata: name: "data" + spec: { + accessModes: [v1.#ReadWriteOnce] + storageClassName: "rook-ceph-nvme" + resources: requests: (v1.#ResourceStorage): "256Mi" + } + }] + serviceName: #Name + } +}]