Browse Source

First commit

Árni Björn Vigfússon 6 hours ago
commit
8b6142c6a1
69 changed files with 6170 additions and 0 deletions
  1. 22 0
      Postgres/Longhorn/instructions.md
  2. 4561 0
      Postgres/Longhorn/longhorn.yml
  3. 5 0
      Postgres/Longhorn/setup.sh
  4. 20 0
      Postgres/postgres-cluster.yaml
  5. 12 0
      Postgres/postgres-loadbalancer.yaml
  6. 16 0
      Postgres/postgres-secrets.yaml
  7. 10 0
      Postgres/setup-postgres.sh
  8. 7 0
      arcadis/Chart.yaml
  9. 15 0
      arcadis/certificate-arcadis.yaml
  10. 6 0
      arcadis/deploy.sh
  11. 34 0
      arcadis/deployment.yaml
  12. 36 0
      arcadis/ingress.yaml
  13. 4 0
      arcadis/namespace.yaml
  14. 18 0
      arcadis/templates/_helpers.tpl
  15. 27 0
      arcadis/templates/certificate.yaml
  16. 45 0
      arcadis/templates/deployment.yaml
  17. 34 0
      arcadis/templates/ingress.yaml
  18. 14 0
      arcadis/templates/issuer-prod.yaml
  19. 14 0
      arcadis/templates/issuer.yaml
  20. 13 0
      arcadis/templates/service.yaml
  21. 34 0
      arcadis/test.yaml
  22. 36 0
      arcadis/values.yaml
  23. 14 0
      cert-manager/certificate-irdi-eu.yaml
  24. 15 0
      cert-manager/cluster-issuer-prod.yaml
  25. 15 0
      cert-manager/cluster-issuer-staging.yaml
  26. 27 0
      cert-manager/setup.sh
  27. 39 0
      gogs/deployment.yaml
  28. 25 0
      gogs/ingress.yaml
  29. 12 0
      gogs/pvc.yaml
  30. 14 0
      gogs/service-ssh.yaml
  31. 16 0
      gogs/service.yaml
  32. 8 0
      gogs/setup.sh
  33. 5 0
      metallb/advertisement.yaml
  34. 8 0
      metallb/ippool.yaml
  35. 1 0
      metallb/setup-metallb.sh
  36. 6 0
      rabbitmq-chart/Chart.yaml
  37. 13 0
      rabbitmq-chart/install.sh
  38. 10 0
      rabbitmq-chart/mqtt-tests/go.mod
  39. 8 0
      rabbitmq-chart/mqtt-tests/go.sum
  40. 64 0
      rabbitmq-chart/mqtt-tests/mqtt.go
  41. BIN
      rabbitmq-chart/mqtt-tests/test-mqtt
  42. 81 0
      rabbitmq-chart/mqtt_test.py
  43. 2 0
      rabbitmq-chart/requirements.txt
  44. 8 0
      rabbitmq-chart/templates/NOTES.txt
  45. 9 0
      rabbitmq-chart/templates/_helpers.tpl
  46. 9 0
      rabbitmq-chart/templates/configmap-definitions.yaml
  47. 9 0
      rabbitmq-chart/templates/configmap-enabled-plugins.yaml
  48. 16 0
      rabbitmq-chart/templates/configmap-rabbitmq-conf.yaml
  49. 27 0
      rabbitmq-chart/templates/ingress.yaml
  50. 8 0
      rabbitmq-chart/templates/secret.yaml
  51. 49 0
      rabbitmq-chart/templates/service.yaml
  52. 103 0
      rabbitmq-chart/templates/statefulset.yaml
  53. 121 0
      rabbitmq-chart/test_mqtt.py
  54. 88 0
      rabbitmq-chart/test_send_mqtt_lb.py
  55. 15 0
      rabbitmq-chart/uninstall.sh
  56. 89 0
      rabbitmq-chart/values.yaml
  57. 6 0
      registry/Chart.yaml
  58. 5 0
      registry/README.md
  59. 5 0
      registry/docker-registry.sh
  60. 35 0
      registry/readme.md
  61. 7 0
      registry/templates/_helpers.tpl
  62. 47 0
      registry/templates/deployment.yaml
  63. 26 0
      registry/templates/ingress.yaml
  64. 11 0
      registry/templates/pvc.yaml
  65. 14 0
      registry/templates/secret.yaml
  66. 15 0
      registry/templates/service.yaml
  67. 31 0
      registry/values.yaml
  68. 11 0
      traefik/install.sh
  69. 40 0
      traefik/values.yaml

+ 22 - 0
Postgres/Longhorn/instructions.md

@@ -0,0 +1,22 @@
+## Install Longhorn (Network Volume Layer)
+
+Longhorn will replicate your Postgres volume across nodes.
+
+## Prereqs on all nodes
+
+sudo apt install -y open-iscsi
+sudo systemctl enable --now iscsid
+
+## Install Longhorn
+
+kubectl apply -f https://raw.githubusercontent.com/longhorn/longhorn/master/deploy/longhorn.yaml
+
+### Wait until everything is running
+
+kubectl -n longhorn-system get pods
+
+### Verify StorageClass
+
+kubectl get storageclass
+
+

+ 4561 - 0
Postgres/Longhorn/longhorn.yml

@@ -0,0 +1,4561 @@
+---
+# Builtin: "helm template" does not respect --create-namespace
+apiVersion: v1
+kind: Namespace
+metadata:
+  name: longhorn-system
+---
+# Source: longhorn/templates/priorityclass.yaml
+apiVersion: scheduling.k8s.io/v1
+kind: PriorityClass
+metadata:
+  name: "longhorn-critical"
+  labels:
+    app.kubernetes.io/name: longhorn
+    app.kubernetes.io/instance: longhorn
+    app.kubernetes.io/version: v1.9.0-dev
+description: "Ensure Longhorn pods have the highest priority to prevent any unexpected eviction by the Kubernetes scheduler under node pressure"
+globalDefault: false
+preemptionPolicy: PreemptLowerPriority
+value: 1000000000
+---
+# Source: longhorn/templates/serviceaccount.yaml
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: longhorn-service-account
+  namespace: longhorn-system
+  labels:
+    app.kubernetes.io/name: longhorn
+    app.kubernetes.io/instance: longhorn
+    app.kubernetes.io/version: v1.9.0-dev
+---
+# Source: longhorn/templates/serviceaccount.yaml
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: longhorn-ui-service-account
+  namespace: longhorn-system
+  labels:
+    app.kubernetes.io/name: longhorn
+    app.kubernetes.io/instance: longhorn
+    app.kubernetes.io/version: v1.9.0-dev
+---
+# Source: longhorn/templates/serviceaccount.yaml
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+  name: longhorn-support-bundle
+  namespace: longhorn-system
+  labels:
+    app.kubernetes.io/name: longhorn
+    app.kubernetes.io/instance: longhorn
+    app.kubernetes.io/version: v1.9.0-dev
+---
+# Source: longhorn/templates/default-resource.yaml
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: longhorn-default-resource
+  namespace: longhorn-system
+  labels:
+    app.kubernetes.io/name: longhorn
+    app.kubernetes.io/instance: longhorn
+    app.kubernetes.io/version: v1.9.0-dev
+data:
+  default-resource.yaml: |-
+---
+# Source: longhorn/templates/default-setting.yaml
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: longhorn-default-setting
+  namespace: longhorn-system
+  labels:
+    app.kubernetes.io/name: longhorn
+    app.kubernetes.io/instance: longhorn
+    app.kubernetes.io/version: v1.9.0-dev
+data:
+  default-setting.yaml: |-
+    priority-class: "longhorn-critical"
+    disable-revision-counter: "{\"v1\":\"true\"}"
+---
+# Source: longhorn/templates/storageclass.yaml
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: longhorn-storageclass
+  namespace: longhorn-system
+  labels:
+    app.kubernetes.io/name: longhorn
+    app.kubernetes.io/instance: longhorn
+    app.kubernetes.io/version: v1.9.0-dev
+data:
+  storageclass.yaml: |
+    kind: StorageClass
+    apiVersion: storage.k8s.io/v1
+    metadata:
+      name: longhorn
+      annotations:
+        storageclass.kubernetes.io/is-default-class: "true"
+    provisioner: driver.longhorn.io
+    allowVolumeExpansion: true
+    reclaimPolicy: "Delete"
+    volumeBindingMode: Immediate
+    parameters:
+      numberOfReplicas: "3"
+      staleReplicaTimeout: "30"
+      fromBackup: ""
+      fsType: "ext4"
+      dataLocality: "disabled"
+      unmapMarkSnapChainRemoved: "ignored"
+      disableRevisionCounter: "true"
+      dataEngine: "v1"
+      backupTargetName: "default"
+---
+# Source: longhorn/templates/crds.yaml
+# Generated crds.yaml from github.com/longhorn/longhorn-manager/k8s/pkg/apis and the crds.yaml will be copied to longhorn/longhorn chart/templates and cannot be directly used by kubectl apply.
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+  annotations:
+    controller-gen.kubebuilder.io/version: v0.19.0
+  labels:
+    app.kubernetes.io/name: longhorn
+    app.kubernetes.io/instance: longhorn
+    app.kubernetes.io/version: v1.9.0-dev
+    longhorn-manager: ""
+  name: backingimagedatasources.longhorn.io
+spec:
+  group: longhorn.io
+  names:
+    kind: BackingImageDataSource
+    listKind: BackingImageDataSourceList
+    plural: backingimagedatasources
+    shortNames:
+    - lhbids
+    singular: backingimagedatasource
+  scope: Namespaced
+  versions:
+  - additionalPrinterColumns:
+    - description: The system generated UUID of the provisioned backing image file
+      jsonPath: .spec.uuid
+      name: UUID
+      type: string
+    - description: The current state of the pod used to provision the backing image
+        file from source
+      jsonPath: .status.currentState
+      name: State
+      type: string
+    - description: The data source type
+      jsonPath: .spec.sourceType
+      name: SourceType
+      type: string
+    - description: The backing image file size
+      jsonPath: .status.size
+      name: Size
+      type: string
+    - description: The node the backing image file will be prepared on
+      jsonPath: .spec.nodeID
+      name: Node
+      type: string
+    - description: The disk the backing image file will be prepared on
+      jsonPath: .spec.diskUUID
+      name: DiskUUID
+      type: string
+    - jsonPath: .metadata.creationTimestamp
+      name: Age
+      type: date
+    name: v1beta2
+    schema:
+      openAPIV3Schema:
+        description: BackingImageDataSource is where Longhorn stores backing image
+          data source object.
+        properties:
+          apiVersion:
+            description: |-
+              APIVersion defines the versioned schema of this representation of an object.
+              Servers should convert recognized schemas to the latest internal value, and
+              may reject unrecognized values.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+            type: string
+          kind:
+            description: |-
+              Kind is a string value representing the REST resource this object represents.
+              Servers may infer this from the endpoint the client submits requests to.
+              Cannot be updated.
+              In CamelCase.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+            type: string
+          metadata:
+            type: object
+          spec:
+            description: BackingImageDataSourceSpec defines the desired state of the
+              Longhorn backing image data source
+            properties:
+              checksum:
+                type: string
+              diskPath:
+                type: string
+              diskUUID:
+                type: string
+              fileTransferred:
+                type: boolean
+              nodeID:
+                type: string
+              parameters:
+                additionalProperties:
+                  type: string
+                type: object
+              sourceType:
+                enum:
+                - download
+                - upload
+                - export-from-volume
+                - restore
+                - clone
+                type: string
+              uuid:
+                type: string
+            type: object
+          status:
+            description: BackingImageDataSourceStatus defines the observed state of
+              the Longhorn backing image data source
+            properties:
+              checksum:
+                type: string
+              currentState:
+                type: string
+              ip:
+                type: string
+              message:
+                type: string
+              ownerID:
+                type: string
+              progress:
+                type: integer
+              runningParameters:
+                additionalProperties:
+                  type: string
+                nullable: true
+                type: object
+              size:
+                format: int64
+                type: integer
+              storageIP:
+                type: string
+            type: object
+        type: object
+    served: true
+    storage: true
+    subresources:
+      status: {}
+---
+# Source: longhorn/templates/crds.yaml
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+  annotations:
+    controller-gen.kubebuilder.io/version: v0.19.0
+  labels:
+    app.kubernetes.io/name: longhorn
+    app.kubernetes.io/instance: longhorn
+    app.kubernetes.io/version: v1.9.0-dev
+    longhorn-manager: ""
+  name: backingimagemanagers.longhorn.io
+spec:
+  group: longhorn.io
+  names:
+    kind: BackingImageManager
+    listKind: BackingImageManagerList
+    plural: backingimagemanagers
+    shortNames:
+    - lhbim
+    singular: backingimagemanager
+  scope: Namespaced
+  versions:
+  - additionalPrinterColumns:
+    - description: The current state of the manager
+      jsonPath: .status.currentState
+      name: State
+      type: string
+    - description: The image the manager pod will use
+      jsonPath: .spec.image
+      name: Image
+      type: string
+    - description: The node the manager is on
+      jsonPath: .spec.nodeID
+      name: Node
+      type: string
+    - description: The disk the manager is responsible for
+      jsonPath: .spec.diskUUID
+      name: DiskUUID
+      type: string
+    - description: The disk path the manager is using
+      jsonPath: .spec.diskPath
+      name: DiskPath
+      type: string
+    - jsonPath: .metadata.creationTimestamp
+      name: Age
+      type: date
+    name: v1beta2
+    schema:
+      openAPIV3Schema:
+        description: BackingImageManager is where Longhorn stores backing image manager
+          object.
+        properties:
+          apiVersion:
+            description: |-
+              APIVersion defines the versioned schema of this representation of an object.
+              Servers should convert recognized schemas to the latest internal value, and
+              may reject unrecognized values.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+            type: string
+          kind:
+            description: |-
+              Kind is a string value representing the REST resource this object represents.
+              Servers may infer this from the endpoint the client submits requests to.
+              Cannot be updated.
+              In CamelCase.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+            type: string
+          metadata:
+            type: object
+          spec:
+            description: BackingImageManagerSpec defines the desired state of the
+              Longhorn backing image manager
+            properties:
+              backingImages:
+                additionalProperties:
+                  type: string
+                type: object
+              diskPath:
+                type: string
+              diskUUID:
+                type: string
+              image:
+                type: string
+              nodeID:
+                type: string
+            type: object
+          status:
+            description: BackingImageManagerStatus defines the observed state of the
+              Longhorn backing image manager
+            properties:
+              apiMinVersion:
+                type: integer
+              apiVersion:
+                type: integer
+              backingImageFileMap:
+                additionalProperties:
+                  properties:
+                    currentChecksum:
+                      type: string
+                    message:
+                      type: string
+                    name:
+                      type: string
+                    progress:
+                      type: integer
+                    realSize:
+                      format: int64
+                      type: integer
+                    senderManagerAddress:
+                      type: string
+                    sendingReference:
+                      type: integer
+                    size:
+                      format: int64
+                      type: integer
+                    state:
+                      type: string
+                    uuid:
+                      type: string
+                    virtualSize:
+                      format: int64
+                      type: integer
+                  type: object
+                nullable: true
+                type: object
+              currentState:
+                type: string
+              ip:
+                type: string
+              ownerID:
+                type: string
+              storageIP:
+                type: string
+            type: object
+        type: object
+    served: true
+    storage: true
+    subresources:
+      status: {}
+---
+# Source: longhorn/templates/crds.yaml
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+  annotations:
+    controller-gen.kubebuilder.io/version: v0.19.0
+  labels:
+    app.kubernetes.io/name: longhorn
+    app.kubernetes.io/instance: longhorn
+    app.kubernetes.io/version: v1.9.0-dev
+    longhorn-manager: ""
+  name: backingimages.longhorn.io
+spec:
+  group: longhorn.io
+  names:
+    kind: BackingImage
+    listKind: BackingImageList
+    plural: backingimages
+    shortNames:
+    - lhbi
+    singular: backingimage
+  scope: Namespaced
+  versions:
+  - additionalPrinterColumns:
+    - description: The system generated UUID
+      jsonPath: .status.uuid
+      name: UUID
+      type: string
+    - description: The source of the backing image file data
+      jsonPath: .spec.sourceType
+      name: SourceType
+      type: string
+    - description: The backing image file size in each disk
+      jsonPath: .status.size
+      name: Size
+      type: string
+    - description: The virtual size of the image (may be larger than file size)
+      jsonPath: .status.virtualSize
+      name: VirtualSize
+      type: string
+    - jsonPath: .metadata.creationTimestamp
+      name: Age
+      type: date
+    name: v1beta2
+    schema:
+      openAPIV3Schema:
+        description: BackingImage is where Longhorn stores backing image object.
+        properties:
+          apiVersion:
+            description: |-
+              APIVersion defines the versioned schema of this representation of an object.
+              Servers should convert recognized schemas to the latest internal value, and
+              may reject unrecognized values.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+            type: string
+          kind:
+            description: |-
+              Kind is a string value representing the REST resource this object represents.
+              Servers may infer this from the endpoint the client submits requests to.
+              Cannot be updated.
+              In CamelCase.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+            type: string
+          metadata:
+            type: object
+          spec:
+            description: BackingImageSpec defines the desired state of the Longhorn
+              backing image
+            properties:
+              checksum:
+                type: string
+              dataEngine:
+                default: v1
+                enum:
+                - v1
+                - v2
+                type: string
+              diskFileSpecMap:
+                additionalProperties:
+                  properties:
+                    dataEngine:
+                      enum:
+                      - v1
+                      - v2
+                      type: string
+                    evictionRequested:
+                      type: boolean
+                  type: object
+                type: object
+              diskSelector:
+                items:
+                  type: string
+                type: array
+              disks:
+                additionalProperties:
+                  type: string
+                description: Deprecated. We are now using DiskFileSpecMap to assign
+                  different spec to the file on different disks.
+                type: object
+              minNumberOfCopies:
+                type: integer
+              nodeSelector:
+                items:
+                  type: string
+                type: array
+              secret:
+                type: string
+              secretNamespace:
+                type: string
+              sourceParameters:
+                additionalProperties:
+                  type: string
+                type: object
+              sourceType:
+                enum:
+                - download
+                - upload
+                - export-from-volume
+                - restore
+                - clone
+                type: string
+            type: object
+          status:
+            description: BackingImageStatus defines the observed state of the Longhorn
+              backing image status
+            properties:
+              checksum:
+                type: string
+              diskFileStatusMap:
+                additionalProperties:
+                  properties:
+                    dataEngine:
+                      enum:
+                      - v1
+                      - v2
+                      type: string
+                    lastStateTransitionTime:
+                      type: string
+                    message:
+                      type: string
+                    progress:
+                      type: integer
+                    state:
+                      type: string
+                  type: object
+                nullable: true
+                type: object
+              diskLastRefAtMap:
+                additionalProperties:
+                  type: string
+                nullable: true
+                type: object
+              ownerID:
+                type: string
+              realSize:
+                description: Real size of image in bytes, which may be smaller than
+                  the size when the file is a sparse file. Will be zero until known
+                  (e.g. while a backing image is uploading)
+                format: int64
+                type: integer
+              size:
+                format: int64
+                type: integer
+              uuid:
+                type: string
+              v2FirstCopyDisk:
+                type: string
+              v2FirstCopyStatus:
+                description: It is pending -> in-progress -> ready/failed
+                type: string
+              virtualSize:
+                description: Virtual size of image in bytes, which may be larger than
+                  physical size. Will be zero until known (e.g. while a backing image
+                  is uploading)
+                format: int64
+                type: integer
+            type: object
+        type: object
+    served: true
+    storage: true
+    subresources:
+      status: {}
+---
+# Source: longhorn/templates/crds.yaml
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+  annotations:
+    controller-gen.kubebuilder.io/version: v0.19.0
+  labels:
+    app.kubernetes.io/name: longhorn
+    app.kubernetes.io/instance: longhorn
+    app.kubernetes.io/version: v1.9.0-dev
+    longhorn-manager: ""
+  name: backupbackingimages.longhorn.io
+spec:
+  group: longhorn.io
+  names:
+    kind: BackupBackingImage
+    listKind: BackupBackingImageList
+    plural: backupbackingimages
+    shortNames:
+    - lhbbi
+    singular: backupbackingimage
+  scope: Namespaced
+  versions:
+  - additionalPrinterColumns:
+    - description: The backing image name
+      jsonPath: .status.backingImage
+      name: BackingImage
+      type: string
+    - description: The backing image size
+      jsonPath: .status.size
+      name: Size
+      type: string
+    - description: The backing image backup upload finished time
+      jsonPath: .status.backupCreatedAt
+      name: BackupCreatedAt
+      type: string
+    - description: The backing image backup state
+      jsonPath: .status.state
+      name: State
+      type: string
+    - description: The last synced time
+      jsonPath: .status.lastSyncedAt
+      name: LastSyncedAt
+      type: string
+    name: v1beta2
+    schema:
+      openAPIV3Schema:
+        description: BackupBackingImage is where Longhorn stores backing image backup
+          object.
+        properties:
+          apiVersion:
+            description: |-
+              APIVersion defines the versioned schema of this representation of an object.
+              Servers should convert recognized schemas to the latest internal value, and
+              may reject unrecognized values.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+            type: string
+          kind:
+            description: |-
+              Kind is a string value representing the REST resource this object represents.
+              Servers may infer this from the endpoint the client submits requests to.
+              Cannot be updated.
+              In CamelCase.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+            type: string
+          metadata:
+            type: object
+          spec:
+            description: BackupBackingImageSpec defines the desired state of the Longhorn
+              backing image backup
+            properties:
+              backingImage:
+                description: The backing image name.
+                type: string
+              backupTargetName:
+                description: The backup target name.
+                nullable: true
+                type: string
+              labels:
+                additionalProperties:
+                  type: string
+                description: The labels of backing image backup.
+                type: object
+              syncRequestedAt:
+                description: The time to request run sync the remote backing image
+                  backup.
+                format: date-time
+                nullable: true
+                type: string
+              userCreated:
+                description: Is this CR created by user through API or UI.
+                type: boolean
+            required:
+            - backingImage
+            - userCreated
+            type: object
+          status:
+            description: BackupBackingImageStatus defines the observed state of the
+              Longhorn backing image backup
+            properties:
+              backingImage:
+                description: The backing image name.
+                type: string
+              backupCreatedAt:
+                description: The backing image backup upload finished time.
+                type: string
+              checksum:
+                description: The checksum of the backing image.
+                type: string
+              compressionMethod:
+                description: Compression method
+                type: string
+              error:
+                description: The error message when taking the backing image backup.
+                type: string
+              labels:
+                additionalProperties:
+                  type: string
+                description: The labels of backing image backup.
+                nullable: true
+                type: object
+              lastSyncedAt:
+                description: The last time that the backing image backup was synced
+                  with the remote backup target.
+                format: date-time
+                nullable: true
+                type: string
+              managerAddress:
+                description: The address of the backing image manager that runs backing
+                  image backup.
+                type: string
+              messages:
+                additionalProperties:
+                  type: string
+                description: The error messages when listing or inspecting backing
+                  image backup.
+                nullable: true
+                type: object
+              ownerID:
+                description: The node ID on which the controller is responsible to
+                  reconcile this CR.
+                type: string
+              progress:
+                description: The backing image backup progress.
+                type: integer
+              secret:
+                description: Record the secret if this backup backing image is encrypted
+                type: string
+              secretNamespace:
+                description: Record the secret namespace if this backup backing image
+                  is encrypted
+                type: string
+              size:
+                description: The backing image size.
+                format: int64
+                type: integer
+              state:
+                description: |-
+                  The backing image backup creation state.
+                  Can be "", "InProgress", "Completed", "Error", "Unknown".
+                type: string
+              url:
+                description: The backing image backup URL.
+                type: string
+            type: object
+        type: object
+    served: true
+    storage: true
+    subresources:
+      status: {}
+---
+# Source: longhorn/templates/crds.yaml
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+  annotations:
+    controller-gen.kubebuilder.io/version: v0.19.0
+  labels:
+    app.kubernetes.io/name: longhorn
+    app.kubernetes.io/instance: longhorn
+    app.kubernetes.io/version: v1.9.0-dev
+    longhorn-manager: ""
+  name: backups.longhorn.io
+spec:
+  group: longhorn.io
+  names:
+    kind: Backup
+    listKind: BackupList
+    plural: backups
+    shortNames:
+    - lhb
+    singular: backup
+  scope: Namespaced
+  versions:
+  - additionalPrinterColumns:
+    - description: The snapshot name
+      jsonPath: .status.snapshotName
+      name: SnapshotName
+      type: string
+    - description: The snapshot size
+      jsonPath: .status.size
+      name: SnapshotSize
+      type: string
+    - description: The snapshot creation time
+      jsonPath: .status.snapshotCreatedAt
+      name: SnapshotCreatedAt
+      type: string
+    - description: The backup target name
+      jsonPath: .status.backupTargetName
+      name: BackupTarget
+      type: string
+    - description: The backup state
+      jsonPath: .status.state
+      name: State
+      type: string
+    - description: The backup last synced time
+      jsonPath: .status.lastSyncedAt
+      name: LastSyncedAt
+      type: string
+    name: v1beta2
+    schema:
+      openAPIV3Schema:
+        description: Backup is where Longhorn stores backup object.
+        properties:
+          apiVersion:
+            description: |-
+              APIVersion defines the versioned schema of this representation of an object.
+              Servers should convert recognized schemas to the latest internal value, and
+              may reject unrecognized values.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+            type: string
+          kind:
+            description: |-
+              Kind is a string value representing the REST resource this object represents.
+              Servers may infer this from the endpoint the client submits requests to.
+              Cannot be updated.
+              In CamelCase.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+            type: string
+          metadata:
+            type: object
+          spec:
+            description: BackupSpec defines the desired state of the Longhorn backup
+            properties:
+              backupBlockSize:
+                description: The backup block size. 0 means the legacy default size
+                  2MiB, and -1 indicate the block size is invalid.
+                enum:
+                - "-1"
+                - "2097152"
+                - "16777216"
+                format: int64
+                type: string
+              backupMode:
+                description: |-
+                  The backup mode of this backup.
+                  Can be "full" or "incremental"
+                enum:
+                - full
+                - incremental
+                type: string
+              labels:
+                additionalProperties:
+                  type: string
+                description: The labels of snapshot backup.
+                type: object
+              snapshotName:
+                description: The snapshot name.
+                type: string
+              syncRequestedAt:
+                description: The time to request run sync the remote backup.
+                format: date-time
+                nullable: true
+                type: string
+            type: object
+          status:
+            description: BackupStatus defines the observed state of the Longhorn backup
+            properties:
+              backupCreatedAt:
+                description: The snapshot backup upload finished time.
+                type: string
+              backupTargetName:
+                description: The backup target name.
+                type: string
+              compressionMethod:
+                description: Compression method
+                type: string
+              error:
+                description: The error message when taking the snapshot backup.
+                type: string
+              labels:
+                additionalProperties:
+                  type: string
+                description: The labels of snapshot backup.
+                nullable: true
+                type: object
+              lastSyncedAt:
+                description: The last time that the backup was synced with the remote
+                  backup target.
+                format: date-time
+                nullable: true
+                type: string
+              messages:
+                additionalProperties:
+                  type: string
+                description: The error messages when calling longhorn engine on listing
+                  or inspecting backups.
+                nullable: true
+                type: object
+              newlyUploadDataSize:
+                description: Size in bytes of newly uploaded data
+                type: string
+              ownerID:
+                description: The node ID on which the controller is responsible to
+                  reconcile this backup CR.
+                type: string
+              progress:
+                description: The snapshot backup progress.
+                type: integer
+              reUploadedDataSize:
+                description: Size in bytes of reuploaded data
+                type: string
+              replicaAddress:
+                description: The address of the replica that runs snapshot backup.
+                type: string
+              size:
+                description: The snapshot size.
+                type: string
+              snapshotCreatedAt:
+                description: The snapshot creation time.
+                type: string
+              snapshotName:
+                description: The snapshot name.
+                type: string
+              state:
+                description: |-
+                  The backup creation state.
+                  Can be "", "InProgress", "Completed", "Error", "Unknown".
+                type: string
+              url:
+                description: The snapshot backup URL.
+                type: string
+              volumeBackingImageName:
+                description: The volume's backing image name.
+                type: string
+              volumeCreated:
+                description: The volume creation time.
+                type: string
+              volumeName:
+                description: The volume name.
+                type: string
+              volumeSize:
+                description: The volume size.
+                type: string
+            type: object
+        type: object
+    served: true
+    storage: true
+    subresources:
+      status: {}
+---
+# Source: longhorn/templates/crds.yaml
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+  annotations:
+    controller-gen.kubebuilder.io/version: v0.19.0
+  labels:
+    app.kubernetes.io/name: longhorn
+    app.kubernetes.io/instance: longhorn
+    app.kubernetes.io/version: v1.9.0-dev
+    longhorn-manager: ""
+  name: backuptargets.longhorn.io
+spec:
+  group: longhorn.io
+  names:
+    kind: BackupTarget
+    listKind: BackupTargetList
+    plural: backuptargets
+    shortNames:
+    - lhbt
+    singular: backuptarget
+  scope: Namespaced
+  versions:
+  - additionalPrinterColumns:
+    - description: The backup target URL
+      jsonPath: .spec.backupTargetURL
+      name: URL
+      type: string
+    - description: The backup target credential secret
+      jsonPath: .spec.credentialSecret
+      name: Credential
+      type: string
+    - description: The backup target poll interval
+      jsonPath: .spec.pollInterval
+      name: LastBackupAt
+      type: string
+    - description: Indicate whether the backup target is available or not
+      jsonPath: .status.available
+      name: Available
+      type: boolean
+    - description: The backup target last synced time
+      jsonPath: .status.lastSyncedAt
+      name: LastSyncedAt
+      type: string
+    name: v1beta2
+    schema:
+      openAPIV3Schema:
+        description: BackupTarget is where Longhorn stores backup target object.
+        properties:
+          apiVersion:
+            description: |-
+              APIVersion defines the versioned schema of this representation of an object.
+              Servers should convert recognized schemas to the latest internal value, and
+              may reject unrecognized values.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+            type: string
+          kind:
+            description: |-
+              Kind is a string value representing the REST resource this object represents.
+              Servers may infer this from the endpoint the client submits requests to.
+              Cannot be updated.
+              In CamelCase.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+            type: string
+          metadata:
+            type: object
+          spec:
+            description: BackupTargetSpec defines the desired state of the Longhorn
+              backup target
+            properties:
+              backupTargetURL:
+                description: The backup target URL.
+                type: string
+              credentialSecret:
+                description: The backup target credential secret.
+                type: string
+              pollInterval:
+                description: The interval that the cluster needs to run sync with
+                  the backup target.
+                type: string
+              syncRequestedAt:
+                description: The time to request run sync the remote backup target.
+                format: date-time
+                nullable: true
+                type: string
+            type: object
+          status:
+            description: BackupTargetStatus defines the observed state of the Longhorn
+              backup target
+            properties:
+              available:
+                description: Available indicates if the remote backup target is available
+                  or not.
+                type: boolean
+              conditions:
+                description: Records the reason on why the backup target is unavailable.
+                items:
+                  properties:
+                    lastProbeTime:
+                      description: Last time we probed the condition.
+                      type: string
+                    lastTransitionTime:
+                      description: Last time the condition transitioned from one status
+                        to another.
+                      type: string
+                    message:
+                      description: Human-readable message indicating details about
+                        last transition.
+                      type: string
+                    reason:
+                      description: Unique, one-word, CamelCase reason for the condition's
+                        last transition.
+                      type: string
+                    status:
+                      description: |-
+                        Status is the status of the condition.
+                        Can be True, False, Unknown.
+                      type: string
+                    type:
+                      description: Type is the type of the condition.
+                      type: string
+                  type: object
+                nullable: true
+                type: array
+              lastSyncedAt:
+                description: The last time that the controller synced with the remote
+                  backup target.
+                format: date-time
+                nullable: true
+                type: string
+              ownerID:
+                description: The node ID on which the controller is responsible to
+                  reconcile this backup target CR.
+                type: string
+            type: object
+        type: object
+    served: true
+    storage: true
+    subresources:
+      status: {}
+---
+# Source: longhorn/templates/crds.yaml
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+  annotations:
+    controller-gen.kubebuilder.io/version: v0.19.0
+  labels:
+    app.kubernetes.io/name: longhorn
+    app.kubernetes.io/instance: longhorn
+    app.kubernetes.io/version: v1.9.0-dev
+    longhorn-manager: ""
+  name: backupvolumes.longhorn.io
+spec:
+  group: longhorn.io
+  names:
+    kind: BackupVolume
+    listKind: BackupVolumeList
+    plural: backupvolumes
+    shortNames:
+    - lhbv
+    singular: backupvolume
+  scope: Namespaced
+  versions:
+  - additionalPrinterColumns:
+    - description: The backup target name
+      jsonPath: .spec.backupTargetName
+      name: BackupTarget
+      type: string
+    - description: The backup volume creation time
+      jsonPath: .status.createdAt
+      name: CreatedAt
+      type: string
+    - description: The backup volume last backup name
+      jsonPath: .status.lastBackupName
+      name: LastBackupName
+      type: string
+    - description: The backup volume last backup time
+      jsonPath: .status.lastBackupAt
+      name: LastBackupAt
+      type: string
+    - description: The backup volume last synced time
+      jsonPath: .status.lastSyncedAt
+      name: LastSyncedAt
+      type: string
+    name: v1beta2
+    schema:
+      openAPIV3Schema:
+        description: BackupVolume is where Longhorn stores backup volume object.
+        properties:
+          apiVersion:
+            description: |-
+              APIVersion defines the versioned schema of this representation of an object.
+              Servers should convert recognized schemas to the latest internal value, and
+              may reject unrecognized values.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+            type: string
+          kind:
+            description: |-
+              Kind is a string value representing the REST resource this object represents.
+              Servers may infer this from the endpoint the client submits requests to.
+              Cannot be updated.
+              In CamelCase.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+            type: string
+          metadata:
+            type: object
+          spec:
+            description: BackupVolumeSpec defines the desired state of the Longhorn
+              backup volume
+            properties:
+              backupTargetName:
+                description: The backup target name that the backup volume was synced.
+                nullable: true
+                type: string
+              syncRequestedAt:
+                description: The time to request run sync the remote backup volume.
+                format: date-time
+                nullable: true
+                type: string
+              volumeName:
+                description: The volume name that the backup volume was used to backup.
+                type: string
+            type: object
+          status:
+            description: BackupVolumeStatus defines the observed state of the Longhorn
+              backup volume
+            properties:
+              backingImageChecksum:
+                description: the backing image checksum.
+                type: string
+              backingImageName:
+                description: The backing image name.
+                type: string
+              createdAt:
+                description: The backup volume creation time.
+                type: string
+              dataStored:
+                description: The backup volume block count.
+                type: string
+              labels:
+                additionalProperties:
+                  type: string
+                description: The backup volume labels.
+                nullable: true
+                type: object
+              lastBackupAt:
+                description: The latest volume backup time.
+                type: string
+              lastBackupName:
+                description: The latest volume backup name.
+                type: string
+              lastModificationTime:
+                description: The backup volume config last modification time.
+                format: date-time
+                nullable: true
+                type: string
+              lastSyncedAt:
+                description: The last time that the backup volume was synced into
+                  the cluster.
+                format: date-time
+                nullable: true
+                type: string
+              messages:
+                additionalProperties:
+                  type: string
+                description: The error messages when call longhorn engine on list
+                  or inspect backup volumes.
+                nullable: true
+                type: object
+              ownerID:
+                description: The node ID on which the controller is responsible to
+                  reconcile this backup volume CR.
+                type: string
+              size:
+                description: The backup volume size.
+                type: string
+              storageClassName:
+                description: the storage class name of pv/pvc binding with the volume.
+                type: string
+            type: object
+        type: object
+    served: true
+    storage: true
+    subresources:
+      status: {}
+---
+# Source: longhorn/templates/crds.yaml
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+  annotations:
+    controller-gen.kubebuilder.io/version: v0.19.0
+  labels:
+    app.kubernetes.io/name: longhorn
+    app.kubernetes.io/instance: longhorn
+    app.kubernetes.io/version: v1.9.0-dev
+    longhorn-manager: ""
+  name: engineimages.longhorn.io
+spec:
+  group: longhorn.io
+  names:
+    kind: EngineImage
+    listKind: EngineImageList
+    plural: engineimages
+    shortNames:
+    - lhei
+    singular: engineimage
+  scope: Namespaced
+  versions:
+  - additionalPrinterColumns:
+    - description: Compatibility of the engine image
+      jsonPath: .status.incompatible
+      name: Incompatible
+      type: boolean
+    - description: State of the engine image
+      jsonPath: .status.state
+      name: State
+      type: string
+    - description: The Longhorn engine image
+      jsonPath: .spec.image
+      name: Image
+      type: string
+    - description: Number of resources using the engine image
+      jsonPath: .status.refCount
+      name: RefCount
+      type: integer
+    - description: The build date of the engine image
+      jsonPath: .status.buildDate
+      name: BuildDate
+      type: date
+    - jsonPath: .metadata.creationTimestamp
+      name: Age
+      type: date
+    name: v1beta2
+    schema:
+      openAPIV3Schema:
+        description: EngineImage is where Longhorn stores engine image object.
+        properties:
+          apiVersion:
+            description: |-
+              APIVersion defines the versioned schema of this representation of an object.
+              Servers should convert recognized schemas to the latest internal value, and
+              may reject unrecognized values.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+            type: string
+          kind:
+            description: |-
+              Kind is a string value representing the REST resource this object represents.
+              Servers may infer this from the endpoint the client submits requests to.
+              Cannot be updated.
+              In CamelCase.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+            type: string
+          metadata:
+            type: object
+          spec:
+            description: EngineImageSpec defines the desired state of the Longhorn
+              engine image
+            properties:
+              image:
+                minLength: 1
+                type: string
+            required:
+            - image
+            type: object
+          status:
+            description: EngineImageStatus defines the observed state of the Longhorn
+              engine image
+            properties:
+              buildDate:
+                type: string
+              cliAPIMinVersion:
+                type: integer
+              cliAPIVersion:
+                type: integer
+              conditions:
+                items:
+                  properties:
+                    lastProbeTime:
+                      description: Last time we probed the condition.
+                      type: string
+                    lastTransitionTime:
+                      description: Last time the condition transitioned from one status
+                        to another.
+                      type: string
+                    message:
+                      description: Human-readable message indicating details about
+                        last transition.
+                      type: string
+                    reason:
+                      description: Unique, one-word, CamelCase reason for the condition's
+                        last transition.
+                      type: string
+                    status:
+                      description: |-
+                        Status is the status of the condition.
+                        Can be True, False, Unknown.
+                      type: string
+                    type:
+                      description: Type is the type of the condition.
+                      type: string
+                  type: object
+                nullable: true
+                type: array
+              controllerAPIMinVersion:
+                type: integer
+              controllerAPIVersion:
+                type: integer
+              dataFormatMinVersion:
+                type: integer
+              dataFormatVersion:
+                type: integer
+              gitCommit:
+                type: string
+              incompatible:
+                type: boolean
+              noRefSince:
+                type: string
+              nodeDeploymentMap:
+                additionalProperties:
+                  type: boolean
+                nullable: true
+                type: object
+              ownerID:
+                type: string
+              refCount:
+                type: integer
+              state:
+                type: string
+              version:
+                type: string
+            type: object
+        type: object
+    served: true
+    storage: true
+    subresources:
+      status: {}
+---
+# Source: longhorn/templates/crds.yaml
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+  annotations:
+    controller-gen.kubebuilder.io/version: v0.19.0
+  labels:
+    app.kubernetes.io/name: longhorn
+    app.kubernetes.io/instance: longhorn
+    app.kubernetes.io/version: v1.9.0-dev
+    longhorn-manager: ""
+  name: engines.longhorn.io
+spec:
+  group: longhorn.io
+  names:
+    kind: Engine
+    listKind: EngineList
+    plural: engines
+    shortNames:
+    - lhe
+    singular: engine
+  scope: Namespaced
+  versions:
+  - additionalPrinterColumns:
+    - description: The data engine of the engine
+      jsonPath: .spec.dataEngine
+      name: Data Engine
+      type: string
+    - description: The current state of the engine
+      jsonPath: .status.currentState
+      name: State
+      type: string
+    - description: The node that the engine is on
+      jsonPath: .spec.nodeID
+      name: Node
+      type: string
+    - description: The instance manager of the engine
+      jsonPath: .status.instanceManagerName
+      name: InstanceManager
+      type: string
+    - description: The current image of the engine
+      jsonPath: .status.currentImage
+      name: Image
+      type: string
+    - jsonPath: .metadata.creationTimestamp
+      name: Age
+      type: date
+    name: v1beta2
+    schema:
+      openAPIV3Schema:
+        description: Engine is where Longhorn stores engine object.
+        properties:
+          apiVersion:
+            description: |-
+              APIVersion defines the versioned schema of this representation of an object.
+              Servers should convert recognized schemas to the latest internal value, and
+              may reject unrecognized values.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+            type: string
+          kind:
+            description: |-
+              Kind is a string value representing the REST resource this object represents.
+              Servers may infer this from the endpoint the client submits requests to.
+              Cannot be updated.
+              In CamelCase.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+            type: string
+          metadata:
+            type: object
+          spec:
+            description: EngineSpec defines the desired state of the Longhorn engine
+            properties:
+              active:
+                type: boolean
+              backupVolume:
+                type: string
+              dataEngine:
+                enum:
+                - v1
+                - v2
+                type: string
+              desireState:
+                type: string
+              disableFrontend:
+                type: boolean
+              frontend:
+                enum:
+                - blockdev
+                - iscsi
+                - nvmf
+                - ublk
+                - ""
+                type: string
+              image:
+                type: string
+              logRequested:
+                type: boolean
+              nodeID:
+                type: string
+              rebuildConcurrentSyncLimit:
+                description: |-
+                  RebuildConcurrentSyncLimit controls the maximum number of file synchronization operations that can run
+                  concurrently during a single replica rebuild.
+                  It is determined by the global setting or the volume spec field with the same name.
+                maximum: 5
+                minimum: 0
+                type: integer
+              replicaAddressMap:
+                additionalProperties:
+                  type: string
+                type: object
+              requestedBackupRestore:
+                type: string
+              requestedDataSource:
+                type: string
+              revisionCounterDisabled:
+                type: boolean
+              salvageRequested:
+                type: boolean
+              snapshotMaxCount:
+                type: integer
+              snapshotMaxSize:
+                format: int64
+                type: string
+              ublkNumberOfQueue:
+                description: ublkNumberOfQueue controls the number of queues for ublk
+                  frontend.
+                type: integer
+              ublkQueueDepth:
+                description: ublkQueueDepth controls the depth of each queue for ublk
+                  frontend.
+                type: integer
+              unmapMarkSnapChainRemovedEnabled:
+                type: boolean
+              upgradedReplicaAddressMap:
+                additionalProperties:
+                  type: string
+                type: object
+              volumeName:
+                type: string
+              volumeSize:
+                format: int64
+                type: string
+            type: object
+          status:
+            description: EngineStatus defines the observed state of the Longhorn engine
+            properties:
+              backupStatus:
+                additionalProperties:
+                  properties:
+                    backupURL:
+                      type: string
+                    error:
+                      type: string
+                    progress:
+                      type: integer
+                    replicaAddress:
+                      type: string
+                    snapshotName:
+                      type: string
+                    state:
+                      type: string
+                  type: object
+                nullable: true
+                type: object
+              cloneStatus:
+                additionalProperties:
+                  properties:
+                    error:
+                      type: string
+                    fromReplicaAddress:
+                      type: string
+                    isCloning:
+                      type: boolean
+                    progress:
+                      type: integer
+                    snapshotName:
+                      type: string
+                    state:
+                      type: string
+                  type: object
+                nullable: true
+                type: object
+              conditions:
+                items:
+                  properties:
+                    lastProbeTime:
+                      description: Last time we probed the condition.
+                      type: string
+                    lastTransitionTime:
+                      description: Last time the condition transitioned from one status
+                        to another.
+                      type: string
+                    message:
+                      description: Human-readable message indicating details about
+                        last transition.
+                      type: string
+                    reason:
+                      description: Unique, one-word, CamelCase reason for the condition's
+                        last transition.
+                      type: string
+                    status:
+                      description: |-
+                        Status is the status of the condition.
+                        Can be True, False, Unknown.
+                      type: string
+                    type:
+                      description: Type is the type of the condition.
+                      type: string
+                  type: object
+                nullable: true
+                type: array
+              currentImage:
+                type: string
+              currentReplicaAddressMap:
+                additionalProperties:
+                  type: string
+                nullable: true
+                type: object
+              currentSize:
+                format: int64
+                type: string
+              currentState:
+                type: string
+              endpoint:
+                type: string
+              instanceManagerName:
+                type: string
+              ip:
+                type: string
+              isExpanding:
+                type: boolean
+              lastExpansionError:
+                type: string
+              lastExpansionFailedAt:
+                type: string
+              lastRestoredBackup:
+                type: string
+              logFetched:
+                type: boolean
+              ownerID:
+                type: string
+              port:
+                type: integer
+              purgeStatus:
+                additionalProperties:
+                  properties:
+                    error:
+                      type: string
+                    isPurging:
+                      type: boolean
+                    progress:
+                      type: integer
+                    state:
+                      type: string
+                  type: object
+                nullable: true
+                type: object
+              rebuildConcurrentSyncLimit:
+                description: |-
+                  RebuildConcurrentSyncLimit controls the maximum number of file synchronization operations that can run
+                  concurrently during a single replica rebuild.
+                  It is determined by the global setting or the volume spec field with the same name.
+                minimum: 0
+                type: integer
+              rebuildStatus:
+                additionalProperties:
+                  properties:
+                    appliedRebuildingMBps:
+                      format: int64
+                      type: integer
+                    error:
+                      type: string
+                    fromReplicaAddress:
+                      description: Deprecated. We are now using FromReplicaAddressList
+                        to list all source replicas.
+                      type: string
+                    fromReplicaAddressList:
+                      items:
+                        type: string
+                      type: array
+                    isRebuilding:
+                      type: boolean
+                    progress:
+                      type: integer
+                    state:
+                      type: string
+                  type: object
+                nullable: true
+                type: object
+              replicaModeMap:
+                additionalProperties:
+                  type: string
+                nullable: true
+                type: object
+              replicaTransitionTimeMap:
+                additionalProperties:
+                  type: string
+                description: |-
+                  ReplicaTransitionTimeMap records the time a replica in ReplicaModeMap transitions from one mode to another (or
+                  from not being in the ReplicaModeMap to being in it). This information is sometimes required by other controllers
+                  (e.g. the volume controller uses it to determine the correct value for replica.Spec.lastHealthyAt).
+                type: object
+              restoreStatus:
+                additionalProperties:
+                  properties:
+                    backupURL:
+                      type: string
+                    currentRestoringBackup:
+                      type: string
+                    error:
+                      type: string
+                    filename:
+                      type: string
+                    isRestoring:
+                      type: boolean
+                    lastRestored:
+                      type: string
+                    progress:
+                      type: integer
+                    state:
+                      type: string
+                  type: object
+                nullable: true
+                type: object
+              salvageExecuted:
+                type: boolean
+              snapshotMaxCount:
+                type: integer
+              snapshotMaxSize:
+                format: int64
+                type: string
+              snapshots:
+                additionalProperties:
+                  properties:
+                    children:
+                      additionalProperties:
+                        type: boolean
+                      nullable: true
+                      type: object
+                    created:
+                      type: string
+                    labels:
+                      additionalProperties:
+                        type: string
+                      nullable: true
+                      type: object
+                    name:
+                      type: string
+                    parent:
+                      type: string
+                    removed:
+                      type: boolean
+                    size:
+                      type: string
+                    usercreated:
+                      type: boolean
+                  type: object
+                nullable: true
+                type: object
+              snapshotsError:
+                type: string
+              started:
+                type: boolean
+              starting:
+                type: boolean
+              storageIP:
+                type: string
+              ublkID:
+                format: int32
+                type: integer
+              unmapMarkSnapChainRemovedEnabled:
+                type: boolean
+              uuid:
+                type: string
+            type: object
+        type: object
+    served: true
+    storage: true
+    subresources:
+      status: {}
+---
+# Source: longhorn/templates/crds.yaml
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+  annotations:
+    controller-gen.kubebuilder.io/version: v0.19.0
+  labels:
+    app.kubernetes.io/name: longhorn
+    app.kubernetes.io/instance: longhorn
+    app.kubernetes.io/version: v1.9.0-dev
+    longhorn-manager: ""
+  name: instancemanagers.longhorn.io
+spec:
+  group: longhorn.io
+  names:
+    kind: InstanceManager
+    listKind: InstanceManagerList
+    plural: instancemanagers
+    shortNames:
+    - lhim
+    singular: instancemanager
+  scope: Namespaced
+  versions:
+  - additionalPrinterColumns:
+    - description: The data engine of the instance manager
+      jsonPath: .spec.dataEngine
+      name: Data Engine
+      type: string
+    - description: The state of the instance manager
+      jsonPath: .status.currentState
+      name: State
+      type: string
+    - description: The type of the instance manager (engine or replica)
+      jsonPath: .spec.type
+      name: Type
+      type: string
+    - description: The node that the instance manager is running on
+      jsonPath: .spec.nodeID
+      name: Node
+      type: string
+    - jsonPath: .metadata.creationTimestamp
+      name: Age
+      type: date
+    name: v1beta2
+    schema:
+      openAPIV3Schema:
+        description: InstanceManager is where Longhorn stores instance manager object.
+        properties:
+          apiVersion:
+            description: |-
+              APIVersion defines the versioned schema of this representation of an object.
+              Servers should convert recognized schemas to the latest internal value, and
+              may reject unrecognized values.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+            type: string
+          kind:
+            description: |-
+              Kind is a string value representing the REST resource this object represents.
+              Servers may infer this from the endpoint the client submits requests to.
+              Cannot be updated.
+              In CamelCase.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+            type: string
+          metadata:
+            type: object
+          spec:
+            description: InstanceManagerSpec defines the desired state of the Longhorn
+              instance manager
+            properties:
+              dataEngine:
+                type: string
+              dataEngineSpec:
+                properties:
+                  v2:
+                    properties:
+                      cpuMask:
+                        type: string
+                    type: object
+                type: object
+              image:
+                type: string
+              nodeID:
+                type: string
+              type:
+                enum:
+                - aio
+                - engine
+                - replica
+                type: string
+            type: object
+          status:
+            description: InstanceManagerStatus defines the observed state of the Longhorn
+              instance manager
+            properties:
+              apiMinVersion:
+                type: integer
+              apiVersion:
+                type: integer
+              backingImages:
+                additionalProperties:
+                  properties:
+                    currentChecksum:
+                      type: string
+                    diskUUID:
+                      type: string
+                    message:
+                      type: string
+                    name:
+                      type: string
+                    progress:
+                      type: integer
+                    size:
+                      format: int64
+                      type: integer
+                    state:
+                      type: string
+                    uuid:
+                      type: string
+                  type: object
+                nullable: true
+                type: object
+              conditions:
+                items:
+                  properties:
+                    lastProbeTime:
+                      description: Last time we probed the condition.
+                      type: string
+                    lastTransitionTime:
+                      description: Last time the condition transitioned from one status
+                        to another.
+                      type: string
+                    message:
+                      description: Human-readable message indicating details about
+                        last transition.
+                      type: string
+                    reason:
+                      description: Unique, one-word, CamelCase reason for the condition's
+                        last transition.
+                      type: string
+                    status:
+                      description: |-
+                        Status is the status of the condition.
+                        Can be True, False, Unknown.
+                      type: string
+                    type:
+                      description: Type is the type of the condition.
+                      type: string
+                  type: object
+                nullable: true
+                type: array
+              currentState:
+                type: string
+              dataEngineStatus:
+                properties:
+                  v2:
+                    properties:
+                      cpuMask:
+                        type: string
+                      interruptModeEnabled:
+                        description: |-
+                          InterruptModeEnabled indicates whether the V2 data engine is running in
+                          interrupt mode (true) or polling mode (false). Set by Longhorn manager;
+                          read-only to users.
+                        enum:
+                        - ""
+                        - "true"
+                        - "false"
+                        type: string
+                    type: object
+                type: object
+              instanceEngines:
+                additionalProperties:
+                  properties:
+                    spec:
+                      properties:
+                        dataEngine:
+                          type: string
+                        name:
+                          type: string
+                      type: object
+                    status:
+                      properties:
+                        conditions:
+                          additionalProperties:
+                            type: boolean
+                          nullable: true
+                          type: object
+                        endpoint:
+                          type: string
+                        errorMsg:
+                          type: string
+                        listen:
+                          type: string
+                        portEnd:
+                          format: int32
+                          type: integer
+                        portStart:
+                          format: int32
+                          type: integer
+                        resourceVersion:
+                          format: int64
+                          type: integer
+                        state:
+                          type: string
+                        targetPortEnd:
+                          format: int32
+                          type: integer
+                        targetPortStart:
+                          format: int32
+                          type: integer
+                        type:
+                          type: string
+                        ublkID:
+                          format: int32
+                          type: integer
+                        uuid:
+                          type: string
+                      type: object
+                  type: object
+                nullable: true
+                type: object
+              instanceReplicas:
+                additionalProperties:
+                  properties:
+                    spec:
+                      properties:
+                        dataEngine:
+                          type: string
+                        name:
+                          type: string
+                      type: object
+                    status:
+                      properties:
+                        conditions:
+                          additionalProperties:
+                            type: boolean
+                          nullable: true
+                          type: object
+                        endpoint:
+                          type: string
+                        errorMsg:
+                          type: string
+                        listen:
+                          type: string
+                        portEnd:
+                          format: int32
+                          type: integer
+                        portStart:
+                          format: int32
+                          type: integer
+                        resourceVersion:
+                          format: int64
+                          type: integer
+                        state:
+                          type: string
+                        targetPortEnd:
+                          format: int32
+                          type: integer
+                        targetPortStart:
+                          format: int32
+                          type: integer
+                        type:
+                          type: string
+                        ublkID:
+                          format: int32
+                          type: integer
+                        uuid:
+                          type: string
+                      type: object
+                  type: object
+                nullable: true
+                type: object
+              ip:
+                type: string
+              ownerID:
+                type: string
+              proxyApiMinVersion:
+                type: integer
+              proxyApiVersion:
+                type: integer
+            type: object
+        type: object
+    served: true
+    storage: true
+    subresources:
+      status: {}
+---
+# Source: longhorn/templates/crds.yaml
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+  annotations:
+    controller-gen.kubebuilder.io/version: v0.19.0
+  labels:
+    app.kubernetes.io/name: longhorn
+    app.kubernetes.io/instance: longhorn
+    app.kubernetes.io/version: v1.9.0-dev
+    longhorn-manager: ""
+  name: nodes.longhorn.io
+spec:
+  group: longhorn.io
+  names:
+    kind: Node
+    listKind: NodeList
+    plural: nodes
+    shortNames:
+    - lhn
+    singular: node
+  scope: Namespaced
+  versions:
+  - additionalPrinterColumns:
+    - description: Indicate whether the node is ready
+      jsonPath: .status.conditions[?(@.type=='Ready')].status
+      name: Ready
+      type: string
+    - description: Indicate whether the user disabled/enabled replica scheduling for
+        the node
+      jsonPath: .spec.allowScheduling
+      name: AllowScheduling
+      type: boolean
+    - description: Indicate whether Longhorn can schedule replicas on the node
+      jsonPath: .status.conditions[?(@.type=='Schedulable')].status
+      name: Schedulable
+      type: string
+    - jsonPath: .metadata.creationTimestamp
+      name: Age
+      type: date
+    name: v1beta2
+    schema:
+      openAPIV3Schema:
+        description: Node is where Longhorn stores Longhorn node object.
+        properties:
+          apiVersion:
+            description: |-
+              APIVersion defines the versioned schema of this representation of an object.
+              Servers should convert recognized schemas to the latest internal value, and
+              may reject unrecognized values.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+            type: string
+          kind:
+            description: |-
+              Kind is a string value representing the REST resource this object represents.
+              Servers may infer this from the endpoint the client submits requests to.
+              Cannot be updated.
+              In CamelCase.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+            type: string
+          metadata:
+            type: object
+          spec:
+            description: NodeSpec defines the desired state of the Longhorn node
+            properties:
+              allowScheduling:
+                type: boolean
+              disks:
+                additionalProperties:
+                  properties:
+                    allowScheduling:
+                      type: boolean
+                    diskDriver:
+                      enum:
+                      - ""
+                      - auto
+                      - aio
+                      - nvme
+                      type: string
+                    diskType:
+                      enum:
+                      - filesystem
+                      - block
+                      type: string
+                    evictionRequested:
+                      type: boolean
+                    path:
+                      type: string
+                    storageReserved:
+                      format: int64
+                      type: integer
+                    tags:
+                      items:
+                        type: string
+                      type: array
+                  type: object
+                type: object
+              evictionRequested:
+                type: boolean
+              instanceManagerCPURequest:
+                type: integer
+              name:
+                type: string
+              tags:
+                items:
+                  type: string
+                type: array
+            type: object
+          status:
+            description: NodeStatus defines the observed state of the Longhorn node
+            properties:
+              autoEvicting:
+                type: boolean
+              conditions:
+                items:
+                  properties:
+                    lastProbeTime:
+                      description: Last time we probed the condition.
+                      type: string
+                    lastTransitionTime:
+                      description: Last time the condition transitioned from one status
+                        to another.
+                      type: string
+                    message:
+                      description: Human-readable message indicating details about
+                        last transition.
+                      type: string
+                    reason:
+                      description: Unique, one-word, CamelCase reason for the condition's
+                        last transition.
+                      type: string
+                    status:
+                      description: |-
+                        Status is the status of the condition.
+                        Can be True, False, Unknown.
+                      type: string
+                    type:
+                      description: Type is the type of the condition.
+                      type: string
+                  type: object
+                nullable: true
+                type: array
+              diskStatus:
+                additionalProperties:
+                  properties:
+                    conditions:
+                      items:
+                        properties:
+                          lastProbeTime:
+                            description: Last time we probed the condition.
+                            type: string
+                          lastTransitionTime:
+                            description: Last time the condition transitioned from
+                              one status to another.
+                            type: string
+                          message:
+                            description: Human-readable message indicating details
+                              about last transition.
+                            type: string
+                          reason:
+                            description: Unique, one-word, CamelCase reason for the
+                              condition's last transition.
+                            type: string
+                          status:
+                            description: |-
+                              Status is the status of the condition.
+                              Can be True, False, Unknown.
+                            type: string
+                          type:
+                            description: Type is the type of the condition.
+                            type: string
+                        type: object
+                      nullable: true
+                      type: array
+                    diskDriver:
+                      type: string
+                    diskName:
+                      type: string
+                    diskPath:
+                      type: string
+                    diskType:
+                      type: string
+                    diskUUID:
+                      type: string
+                    filesystemType:
+                      type: string
+                    healthData:
+                      additionalProperties:
+                        properties:
+                          attributes:
+                            items:
+                              properties:
+                                id:
+                                  type: integer
+                                name:
+                                  type: string
+                                rawString:
+                                  type: string
+                                rawValue:
+                                  format: int64
+                                  type: integer
+                                threshold:
+                                  type: integer
+                                value:
+                                  type: integer
+                                whenFailed:
+                                  type: string
+                                worst:
+                                  type: integer
+                              type: object
+                            type: array
+                          capacity:
+                            format: int64
+                            type: integer
+                          diskName:
+                            type: string
+                          diskType:
+                            type: string
+                          firmwareVersion:
+                            type: string
+                          healthStatus:
+                            enum:
+                            - FAILED
+                            - PASSED
+                            - UNKNOWN
+                            - WARNING
+                            type: string
+                          modelName:
+                            type: string
+                          serialNumber:
+                            type: string
+                          source:
+                            enum:
+                            - SMART
+                            - SPDK
+                            type: string
+                          temperature:
+                            type: integer
+                        type: object
+                      type: object
+                    healthDataLastCollectedAt:
+                      format: date-time
+                      type: string
+                    instanceManagerName:
+                      type: string
+                    scheduledBackingImage:
+                      additionalProperties:
+                        format: int64
+                        type: integer
+                      nullable: true
+                      type: object
+                    scheduledReplica:
+                      additionalProperties:
+                        format: int64
+                        type: integer
+                      nullable: true
+                      type: object
+                    storageAvailable:
+                      format: int64
+                      type: integer
+                    storageMaximum:
+                      format: int64
+                      type: integer
+                    storageScheduled:
+                      format: int64
+                      type: integer
+                  type: object
+                nullable: true
+                type: object
+              region:
+                type: string
+              snapshotCheckStatus:
+                properties:
+                  lastPeriodicCheckedAt:
+                    format: date-time
+                    type: string
+                type: object
+              zone:
+                type: string
+            type: object
+        type: object
+    served: true
+    storage: true
+    subresources:
+      status: {}
+---
+# Source: longhorn/templates/crds.yaml
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+  annotations:
+    controller-gen.kubebuilder.io/version: v0.19.0
+  labels:
+    app.kubernetes.io/name: longhorn
+    app.kubernetes.io/instance: longhorn
+    app.kubernetes.io/version: v1.9.0-dev
+    longhorn-manager: ""
+  name: orphans.longhorn.io
+spec:
+  group: longhorn.io
+  names:
+    kind: Orphan
+    listKind: OrphanList
+    plural: orphans
+    shortNames:
+    - lho
+    singular: orphan
+  scope: Namespaced
+  versions:
+  - additionalPrinterColumns:
+    - description: The type of the orphan
+      jsonPath: .spec.orphanType
+      name: Type
+      type: string
+    - description: The node that the orphan is on
+      jsonPath: .spec.nodeID
+      name: Node
+      type: string
+    name: v1beta2
+    schema:
+      openAPIV3Schema:
+        description: Orphan is where Longhorn stores orphan object.
+        properties:
+          apiVersion:
+            description: |-
+              APIVersion defines the versioned schema of this representation of an object.
+              Servers should convert recognized schemas to the latest internal value, and
+              may reject unrecognized values.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+            type: string
+          kind:
+            description: |-
+              Kind is a string value representing the REST resource this object represents.
+              Servers may infer this from the endpoint the client submits requests to.
+              Cannot be updated.
+              In CamelCase.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+            type: string
+          metadata:
+            type: object
+          spec:
+            description: OrphanSpec defines the desired state of the Longhorn orphaned
+              data
+            properties:
+              dataEngine:
+                description: |-
+                  The type of data engine for instance orphan.
+                  Can be "v1", "v2".
+                enum:
+                - v1
+                - v2
+                type: string
+              nodeID:
+                description: The node ID on which the controller is responsible to
+                  reconcile this orphan CR.
+                type: string
+              orphanType:
+                description: |-
+                  The type of the orphaned data.
+                  Can be "replica".
+                type: string
+              parameters:
+                additionalProperties:
+                  type: string
+                description: The parameters of the orphaned data
+                type: object
+            type: object
+          status:
+            description: OrphanStatus defines the observed state of the Longhorn orphaned
+              data
+            properties:
+              conditions:
+                items:
+                  properties:
+                    lastProbeTime:
+                      description: Last time we probed the condition.
+                      type: string
+                    lastTransitionTime:
+                      description: Last time the condition transitioned from one status
+                        to another.
+                      type: string
+                    message:
+                      description: Human-readable message indicating details about
+                        last transition.
+                      type: string
+                    reason:
+                      description: Unique, one-word, CamelCase reason for the condition's
+                        last transition.
+                      type: string
+                    status:
+                      description: |-
+                        Status is the status of the condition.
+                        Can be True, False, Unknown.
+                      type: string
+                    type:
+                      description: Type is the type of the condition.
+                      type: string
+                  type: object
+                nullable: true
+                type: array
+              ownerID:
+                type: string
+            type: object
+        type: object
+    served: true
+    storage: true
+    subresources:
+      status: {}
+---
+# Source: longhorn/templates/crds.yaml
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+  annotations:
+    controller-gen.kubebuilder.io/version: v0.19.0
+  labels:
+    app.kubernetes.io/name: longhorn
+    app.kubernetes.io/instance: longhorn
+    app.kubernetes.io/version: v1.9.0-dev
+    longhorn-manager: ""
+  name: recurringjobs.longhorn.io
+spec:
+  group: longhorn.io
+  names:
+    kind: RecurringJob
+    listKind: RecurringJobList
+    plural: recurringjobs
+    shortNames:
+    - lhrj
+    singular: recurringjob
+  scope: Namespaced
+  versions:
+  - additionalPrinterColumns:
+    - description: Sets groupings to the jobs. When set to "default" group will be
+        added to the volume label when no other job label exist in volume
+      jsonPath: .spec.groups
+      name: Groups
+      type: string
+    - description: Should be one of "snapshot", "snapshot-force-create", "snapshot-cleanup",
+        "snapshot-delete", "backup", "backup-force-create", "filesystem-trim" or "system-backup"
+      jsonPath: .spec.task
+      name: Task
+      type: string
+    - description: The cron expression represents recurring job scheduling
+      jsonPath: .spec.cron
+      name: Cron
+      type: string
+    - description: The number of snapshots/backups to keep for the volume
+      jsonPath: .spec.retain
+      name: Retain
+      type: integer
+    - description: The concurrent job to run by each cron job
+      jsonPath: .spec.concurrency
+      name: Concurrency
+      type: integer
+    - jsonPath: .metadata.creationTimestamp
+      name: Age
+      type: date
+    - description: Specify the labels
+      jsonPath: .spec.labels
+      name: Labels
+      type: string
+    name: v1beta2
+    schema:
+      openAPIV3Schema:
+        description: RecurringJob is where Longhorn stores recurring job object.
+        properties:
+          apiVersion:
+            description: |-
+              APIVersion defines the versioned schema of this representation of an object.
+              Servers should convert recognized schemas to the latest internal value, and
+              may reject unrecognized values.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+            type: string
+          kind:
+            description: |-
+              Kind is a string value representing the REST resource this object represents.
+              Servers may infer this from the endpoint the client submits requests to.
+              Cannot be updated.
+              In CamelCase.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+            type: string
+          metadata:
+            type: object
+          spec:
+            description: RecurringJobSpec defines the desired state of the Longhorn
+              recurring job
+            properties:
+              concurrency:
+                description: The concurrency of taking the snapshot/backup.
+                type: integer
+              cron:
+                description: The cron setting.
+                type: string
+              groups:
+                description: The recurring job group.
+                items:
+                  type: string
+                type: array
+              labels:
+                additionalProperties:
+                  type: string
+                description: The label of the snapshot/backup.
+                type: object
+              name:
+                description: The recurring job name.
+                type: string
+              parameters:
+                additionalProperties:
+                  type: string
+                description: |-
+                  The parameters of the snapshot/backup.
+                  Support parameters: "full-backup-interval", "volume-backup-policy".
+                type: object
+              retain:
+                description: The retain count of the snapshot/backup.
+                type: integer
+              task:
+                description: |-
+                  The recurring job task.
+                  Can be "snapshot", "snapshot-force-create", "snapshot-cleanup", "snapshot-delete", "backup", "backup-force-create", "filesystem-trim" or "system-backup".
+                enum:
+                - snapshot
+                - snapshot-force-create
+                - snapshot-cleanup
+                - snapshot-delete
+                - backup
+                - backup-force-create
+                - filesystem-trim
+                - system-backup
+                type: string
+            type: object
+          status:
+            description: RecurringJobStatus defines the observed state of the Longhorn
+              recurring job
+            properties:
+              executionCount:
+                description: The number of jobs that have been triggered.
+                type: integer
+              ownerID:
+                description: The owner ID which is responsible to reconcile this recurring
+                  job CR.
+                type: string
+            type: object
+        type: object
+    served: true
+    storage: true
+    subresources:
+      status: {}
+---
+# Source: longhorn/templates/crds.yaml
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+  annotations:
+    controller-gen.kubebuilder.io/version: v0.19.0
+  labels:
+    app.kubernetes.io/name: longhorn
+    app.kubernetes.io/instance: longhorn
+    app.kubernetes.io/version: v1.9.0-dev
+    longhorn-manager: ""
+  name: replicas.longhorn.io
+spec:
+  group: longhorn.io
+  names:
+    kind: Replica
+    listKind: ReplicaList
+    plural: replicas
+    shortNames:
+    - lhr
+    singular: replica
+  scope: Namespaced
+  versions:
+  - additionalPrinterColumns:
+    - description: The data engine of the replica
+      jsonPath: .spec.dataEngine
+      name: Data Engine
+      type: string
+    - description: The current state of the replica
+      jsonPath: .status.currentState
+      name: State
+      type: string
+    - description: The node that the replica is on
+      jsonPath: .spec.nodeID
+      name: Node
+      type: string
+    - description: The disk that the replica is on
+      jsonPath: .spec.diskID
+      name: Disk
+      type: string
+    - description: The instance manager of the replica
+      jsonPath: .status.instanceManagerName
+      name: InstanceManager
+      type: string
+    - description: The current image of the replica
+      jsonPath: .status.currentImage
+      name: Image
+      type: string
+    - jsonPath: .metadata.creationTimestamp
+      name: Age
+      type: date
+    name: v1beta2
+    schema:
+      openAPIV3Schema:
+        description: Replica is where Longhorn stores replica object.
+        properties:
+          apiVersion:
+            description: |-
+              APIVersion defines the versioned schema of this representation of an object.
+              Servers should convert recognized schemas to the latest internal value, and
+              may reject unrecognized values.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+            type: string
+          kind:
+            description: |-
+              Kind is a string value representing the REST resource this object represents.
+              Servers may infer this from the endpoint the client submits requests to.
+              Cannot be updated.
+              In CamelCase.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+            type: string
+          metadata:
+            type: object
+          spec:
+            description: ReplicaSpec defines the desired state of the Longhorn replica
+            properties:
+              active:
+                type: boolean
+              backingImage:
+                type: string
+              dataDirectoryName:
+                type: string
+              dataEngine:
+                enum:
+                - v1
+                - v2
+                type: string
+              desireState:
+                type: string
+              diskID:
+                type: string
+              diskPath:
+                type: string
+              engineName:
+                type: string
+              evictionRequested:
+                type: boolean
+              failedAt:
+                description: |-
+                  FailedAt is set when a running replica fails or when a running engine is unable to use a replica for any reason.
+                  FailedAt indicates the time the failure occurred. When FailedAt is set, a replica is likely to have useful
+                  (though possibly stale) data. A replica with FailedAt set must be rebuilt from a non-failed replica (or it can
+                  be used in a salvage if all replicas are failed). FailedAt is cleared before a rebuild or salvage. FailedAt may
+                  be later than the corresponding entry in an engine's replicaTransitionTimeMap because it is set when the volume
+                  controller acknowledges the change.
+                type: string
+              hardNodeAffinity:
+                type: string
+              healthyAt:
+                description: |-
+                  HealthyAt is set the first time a replica becomes read/write in an engine after creation or rebuild. HealthyAt
+                  indicates the time the last successful rebuild occurred. When HealthyAt is set, a replica is likely to have
+                  useful (though possibly stale) data. HealthyAt is cleared before a rebuild. HealthyAt may be later than the
+                  corresponding entry in an engine's replicaTransitionTimeMap because it is set when the volume controller
+                  acknowledges the change.
+                type: string
+              image:
+                type: string
+              lastFailedAt:
+                description: |-
+                  LastFailedAt is always set at the same time as FailedAt. Unlike FailedAt, LastFailedAt is never cleared.
+                  LastFailedAt is not a reliable indicator of the state of a replica's data. For example, a replica with
+                  LastFailedAt may already be healthy and in use again. However, because it is never cleared, it can be compared to
+                  LastHealthyAt to help prevent dangerous replica deletion in some corner cases. LastFailedAt may be later than the
+                  corresponding entry in an engine's replicaTransitionTimeMap because it is set when the volume controller
+                  acknowledges the change.
+                type: string
+              lastHealthyAt:
+                description: |-
+                  LastHealthyAt is set every time a replica becomes read/write in an engine. Unlike HealthyAt, LastHealthyAt is
+                  never cleared. LastHealthyAt is not a reliable indicator of the state of a replica's data. For example, a
+                  replica with LastHealthyAt set may be in the middle of a rebuild. However, because it is never cleared, it can be
+                  compared to LastFailedAt to help prevent dangerous replica deletion in some corner cases. LastHealthyAt may be
+                  later than the corresponding entry in an engine's replicaTransitionTimeMap because it is set when the volume
+                  controller acknowledges the change.
+                type: string
+              logRequested:
+                type: boolean
+              migrationEngineName:
+                description: |-
+                  MigrationEngineName is indicating the migrating engine which current connected to this replica. This is only
+                  used for live migration of v2 data engine
+                type: string
+              nodeID:
+                type: string
+              rebuildRetryCount:
+                type: integer
+              revisionCounterDisabled:
+                type: boolean
+              salvageRequested:
+                type: boolean
+              snapshotMaxCount:
+                type: integer
+              snapshotMaxSize:
+                format: int64
+                type: string
+              unmapMarkDiskChainRemovedEnabled:
+                type: boolean
+              volumeName:
+                type: string
+              volumeSize:
+                format: int64
+                type: string
+            type: object
+          status:
+            description: ReplicaStatus defines the observed state of the Longhorn
+              replica
+            properties:
+              conditions:
+                items:
+                  properties:
+                    lastProbeTime:
+                      description: Last time we probed the condition.
+                      type: string
+                    lastTransitionTime:
+                      description: Last time the condition transitioned from one status
+                        to another.
+                      type: string
+                    message:
+                      description: Human-readable message indicating details about
+                        last transition.
+                      type: string
+                    reason:
+                      description: Unique, one-word, CamelCase reason for the condition's
+                        last transition.
+                      type: string
+                    status:
+                      description: |-
+                        Status is the status of the condition.
+                        Can be True, False, Unknown.
+                      type: string
+                    type:
+                      description: Type is the type of the condition.
+                      type: string
+                  type: object
+                nullable: true
+                type: array
+              currentImage:
+                type: string
+              currentState:
+                type: string
+              instanceManagerName:
+                type: string
+              ip:
+                type: string
+              logFetched:
+                type: boolean
+              ownerID:
+                type: string
+              port:
+                type: integer
+              salvageExecuted:
+                type: boolean
+              started:
+                type: boolean
+              starting:
+                type: boolean
+              storageIP:
+                type: string
+              ublkID:
+                format: int32
+                type: integer
+              uuid:
+                type: string
+            type: object
+        type: object
+    served: true
+    storage: true
+    subresources:
+      status: {}
+---
+# Source: longhorn/templates/crds.yaml
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+  annotations:
+    controller-gen.kubebuilder.io/version: v0.19.0
+  labels:
+    app.kubernetes.io/name: longhorn
+    app.kubernetes.io/instance: longhorn
+    app.kubernetes.io/version: v1.9.0-dev
+    longhorn-manager: ""
+  name: settings.longhorn.io
+spec:
+  group: longhorn.io
+  names:
+    kind: Setting
+    listKind: SettingList
+    plural: settings
+    shortNames:
+    - lhs
+    singular: setting
+  scope: Namespaced
+  versions:
+  - additionalPrinterColumns:
+    - description: The value of the setting
+      jsonPath: .value
+      name: Value
+      type: string
+    - description: The setting is applied
+      jsonPath: .status.applied
+      name: Applied
+      type: boolean
+    - jsonPath: .metadata.creationTimestamp
+      name: Age
+      type: date
+    name: v1beta2
+    schema:
+      openAPIV3Schema:
+        description: Setting is where Longhorn stores setting object.
+        properties:
+          apiVersion:
+            description: |-
+              APIVersion defines the versioned schema of this representation of an object.
+              Servers should convert recognized schemas to the latest internal value, and
+              may reject unrecognized values.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+            type: string
+          kind:
+            description: |-
+              Kind is a string value representing the REST resource this object represents.
+              Servers may infer this from the endpoint the client submits requests to.
+              Cannot be updated.
+              In CamelCase.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+            type: string
+          metadata:
+            type: object
+          status:
+            description: The status of the setting.
+            properties:
+              applied:
+                description: The setting is applied.
+                type: boolean
+            required:
+            - applied
+            type: object
+          value:
+            description: |-
+              The value of the setting.
+              - It can be a non-JSON formatted string that is applied to all the applicable data engines listed in the setting definition.
+              - It can be a JSON formatted string that contains values for applicable data engines listed in the setting definition's Default.
+            type: string
+        required:
+        - value
+        type: object
+    served: true
+    storage: true
+    subresources:
+      status: {}
+---
+# Source: longhorn/templates/crds.yaml
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+  annotations:
+    controller-gen.kubebuilder.io/version: v0.19.0
+  labels:
+    app.kubernetes.io/name: longhorn
+    app.kubernetes.io/instance: longhorn
+    app.kubernetes.io/version: v1.9.0-dev
+    longhorn-manager: ""
+  name: sharemanagers.longhorn.io
+spec:
+  group: longhorn.io
+  names:
+    kind: ShareManager
+    listKind: ShareManagerList
+    plural: sharemanagers
+    shortNames:
+    - lhsm
+    singular: sharemanager
+  scope: Namespaced
+  versions:
+  - additionalPrinterColumns:
+    - description: The state of the share manager
+      jsonPath: .status.state
+      name: State
+      type: string
+    - description: The node that the share manager is owned by
+      jsonPath: .status.ownerID
+      name: Node
+      type: string
+    - jsonPath: .metadata.creationTimestamp
+      name: Age
+      type: date
+    name: v1beta2
+    schema:
+      openAPIV3Schema:
+        description: ShareManager is where Longhorn stores share manager object.
+        properties:
+          apiVersion:
+            description: |-
+              APIVersion defines the versioned schema of this representation of an object.
+              Servers should convert recognized schemas to the latest internal value, and
+              may reject unrecognized values.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+            type: string
+          kind:
+            description: |-
+              Kind is a string value representing the REST resource this object represents.
+              Servers may infer this from the endpoint the client submits requests to.
+              Cannot be updated.
+              In CamelCase.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+            type: string
+          metadata:
+            type: object
+          spec:
+            description: ShareManagerSpec defines the desired state of the Longhorn
+              share manager
+            properties:
+              image:
+                description: Share manager image used for creating a share manager
+                  pod
+                type: string
+            type: object
+          status:
+            description: ShareManagerStatus defines the observed state of the Longhorn
+              share manager
+            properties:
+              endpoint:
+                description: NFS endpoint that can access the mounted filesystem of
+                  the volume
+                type: string
+              ownerID:
+                description: The node ID on which the controller is responsible to
+                  reconcile this share manager resource
+                type: string
+              state:
+                description: The state of the share manager resource
+                type: string
+            type: object
+        type: object
+    served: true
+    storage: true
+    subresources:
+      status: {}
+---
+# Source: longhorn/templates/crds.yaml
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+  annotations:
+    controller-gen.kubebuilder.io/version: v0.19.0
+  labels:
+    app.kubernetes.io/name: longhorn
+    app.kubernetes.io/instance: longhorn
+    app.kubernetes.io/version: v1.9.0-dev
+    longhorn-manager: ""
+  name: snapshots.longhorn.io
+spec:
+  group: longhorn.io
+  names:
+    kind: Snapshot
+    listKind: SnapshotList
+    plural: snapshots
+    shortNames:
+    - lhsnap
+    singular: snapshot
+  scope: Namespaced
+  versions:
+  - additionalPrinterColumns:
+    - description: The volume that this snapshot belongs to
+      jsonPath: .spec.volume
+      name: Volume
+      type: string
+    - description: Timestamp when the point-in-time snapshot was taken
+      jsonPath: .status.creationTime
+      name: CreationTime
+      type: string
+    - description: Indicates if the snapshot is ready to be used to restore/backup
+        a volume
+      jsonPath: .status.readyToUse
+      name: ReadyToUse
+      type: boolean
+    - description: Represents the minimum size of volume required to rehydrate from
+        this snapshot
+      jsonPath: .status.restoreSize
+      name: RestoreSize
+      type: string
+    - description: The actual size of the snapshot
+      jsonPath: .status.size
+      name: Size
+      type: string
+    - jsonPath: .metadata.creationTimestamp
+      name: Age
+      type: date
+    name: v1beta2
+    schema:
+      openAPIV3Schema:
+        description: Snapshot is the Schema for the snapshots API
+        properties:
+          apiVersion:
+            description: |-
+              APIVersion defines the versioned schema of this representation of an object.
+              Servers should convert recognized schemas to the latest internal value, and
+              may reject unrecognized values.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+            type: string
+          kind:
+            description: |-
+              Kind is a string value representing the REST resource this object represents.
+              Servers may infer this from the endpoint the client submits requests to.
+              Cannot be updated.
+              In CamelCase.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+            type: string
+          metadata:
+            type: object
+          spec:
+            description: SnapshotSpec defines the desired state of Longhorn Snapshot
+            properties:
+              createSnapshot:
+                description: require creating a new snapshot
+                type: boolean
+              labels:
+                additionalProperties:
+                  type: string
+                description: The labels of snapshot
+                nullable: true
+                type: object
+              volume:
+                description: |-
+                  the volume that this snapshot belongs to.
+                  This field is immutable after creation.
+                type: string
+            required:
+            - volume
+            type: object
+          status:
+            description: SnapshotStatus defines the observed state of Longhorn Snapshot
+            properties:
+              checksum:
+                type: string
+              children:
+                additionalProperties:
+                  type: boolean
+                nullable: true
+                type: object
+              creationTime:
+                type: string
+              error:
+                type: string
+              labels:
+                additionalProperties:
+                  type: string
+                nullable: true
+                type: object
+              markRemoved:
+                type: boolean
+              ownerID:
+                type: string
+              parent:
+                type: string
+              readyToUse:
+                type: boolean
+              restoreSize:
+                format: int64
+                type: integer
+              size:
+                format: int64
+                type: integer
+              userCreated:
+                type: boolean
+            type: object
+        type: object
+    served: true
+    storage: true
+    subresources:
+      status: {}
+---
+# Source: longhorn/templates/crds.yaml
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+  annotations:
+    controller-gen.kubebuilder.io/version: v0.19.0
+  labels:
+    app.kubernetes.io/name: longhorn
+    app.kubernetes.io/instance: longhorn
+    app.kubernetes.io/version: v1.9.0-dev
+    longhorn-manager: ""
+  name: supportbundles.longhorn.io
+spec:
+  group: longhorn.io
+  names:
+    kind: SupportBundle
+    listKind: SupportBundleList
+    plural: supportbundles
+    shortNames:
+    - lhbundle
+    singular: supportbundle
+  scope: Namespaced
+  versions:
+  - additionalPrinterColumns:
+    - description: The state of the support bundle
+      jsonPath: .status.state
+      name: State
+      type: string
+    - description: The issue URL
+      jsonPath: .spec.issueURL
+      name: Issue
+      type: string
+    - description: A brief description of the issue
+      jsonPath: .spec.description
+      name: Description
+      type: string
+    - jsonPath: .metadata.creationTimestamp
+      name: Age
+      type: date
+    name: v1beta2
+    schema:
+      openAPIV3Schema:
+        description: SupportBundle is where Longhorn stores support bundle object
+        properties:
+          apiVersion:
+            description: |-
+              APIVersion defines the versioned schema of this representation of an object.
+              Servers should convert recognized schemas to the latest internal value, and
+              may reject unrecognized values.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+            type: string
+          kind:
+            description: |-
+              Kind is a string value representing the REST resource this object represents.
+              Servers may infer this from the endpoint the client submits requests to.
+              Cannot be updated.
+              In CamelCase.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+            type: string
+          metadata:
+            type: object
+          spec:
+            description: SupportBundleSpec defines the desired state of the Longhorn
+              SupportBundle
+            properties:
+              description:
+                description: A brief description of the issue
+                type: string
+              issueURL:
+                description: The issue URL
+                nullable: true
+                type: string
+              nodeID:
+                description: The preferred responsible controller node ID.
+                type: string
+            required:
+            - description
+            type: object
+          status:
+            description: SupportBundleStatus defines the observed state of the Longhorn
+              SupportBundle
+            properties:
+              conditions:
+                items:
+                  properties:
+                    lastProbeTime:
+                      description: Last time we probed the condition.
+                      type: string
+                    lastTransitionTime:
+                      description: Last time the condition transitioned from one status
+                        to another.
+                      type: string
+                    message:
+                      description: Human-readable message indicating details about
+                        last transition.
+                      type: string
+                    reason:
+                      description: Unique, one-word, CamelCase reason for the condition's
+                        last transition.
+                      type: string
+                    status:
+                      description: |-
+                        Status is the status of the condition.
+                        Can be True, False, Unknown.
+                      type: string
+                    type:
+                      description: Type is the type of the condition.
+                      type: string
+                  type: object
+                type: array
+              filename:
+                type: string
+              filesize:
+                format: int64
+                type: integer
+              image:
+                description: The support bundle manager image
+                type: string
+              managerIP:
+                description: The support bundle manager IP
+                type: string
+              ownerID:
+                description: The current responsible controller node ID
+                type: string
+              progress:
+                type: integer
+              state:
+                type: string
+            type: object
+        type: object
+    served: true
+    storage: true
+    subresources:
+      status: {}
+---
+# Source: longhorn/templates/crds.yaml
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+  annotations:
+    controller-gen.kubebuilder.io/version: v0.19.0
+  labels:
+    app.kubernetes.io/name: longhorn
+    app.kubernetes.io/instance: longhorn
+    app.kubernetes.io/version: v1.9.0-dev
+    longhorn-manager: ""
+  name: systembackups.longhorn.io
+spec:
+  group: longhorn.io
+  names:
+    kind: SystemBackup
+    listKind: SystemBackupList
+    plural: systembackups
+    shortNames:
+    - lhsb
+    singular: systembackup
+  scope: Namespaced
+  versions:
+  - additionalPrinterColumns:
+    - description: The system backup Longhorn version
+      jsonPath: .status.version
+      name: Version
+      type: string
+    - description: The system backup state
+      jsonPath: .status.state
+      name: State
+      type: string
+    - description: The system backup creation time
+      jsonPath: .status.createdAt
+      name: Created
+      type: string
+    - description: The last time that the system backup was synced into the cluster
+      jsonPath: .status.lastSyncedAt
+      name: LastSyncedAt
+      type: string
+    name: v1beta2
+    schema:
+      openAPIV3Schema:
+        description: SystemBackup is where Longhorn stores system backup object
+        properties:
+          apiVersion:
+            description: |-
+              APIVersion defines the versioned schema of this representation of an object.
+              Servers should convert recognized schemas to the latest internal value, and
+              may reject unrecognized values.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+            type: string
+          kind:
+            description: |-
+              Kind is a string value representing the REST resource this object represents.
+              Servers may infer this from the endpoint the client submits requests to.
+              Cannot be updated.
+              In CamelCase.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+            type: string
+          metadata:
+            type: object
+          spec:
+            description: SystemBackupSpec defines the desired state of the Longhorn
+              SystemBackup
+            properties:
+              volumeBackupPolicy:
+                description: |-
+                  The create volume backup policy
+                  Can be "if-not-present", "always" or "disabled"
+                nullable: true
+                type: string
+            type: object
+          status:
+            description: SystemBackupStatus defines the observed state of the Longhorn
+              SystemBackup
+            properties:
+              conditions:
+                items:
+                  properties:
+                    lastProbeTime:
+                      description: Last time we probed the condition.
+                      type: string
+                    lastTransitionTime:
+                      description: Last time the condition transitioned from one status
+                        to another.
+                      type: string
+                    message:
+                      description: Human-readable message indicating details about
+                        last transition.
+                      type: string
+                    reason:
+                      description: Unique, one-word, CamelCase reason for the condition's
+                        last transition.
+                      type: string
+                    status:
+                      description: |-
+                        Status is the status of the condition.
+                        Can be True, False, Unknown.
+                      type: string
+                    type:
+                      description: Type is the type of the condition.
+                      type: string
+                  type: object
+                nullable: true
+                type: array
+              createdAt:
+                description: The system backup creation time.
+                format: date-time
+                type: string
+              gitCommit:
+                description: The saved Longhorn manager git commit.
+                nullable: true
+                type: string
+              lastSyncedAt:
+                description: The last time that the system backup was synced into
+                  the cluster.
+                format: date-time
+                nullable: true
+                type: string
+              managerImage:
+                description: The saved manager image.
+                type: string
+              ownerID:
+                description: The node ID of the responsible controller to reconcile
+                  this SystemBackup.
+                type: string
+              state:
+                description: The system backup state.
+                type: string
+              version:
+                description: The saved Longhorn version.
+                nullable: true
+                type: string
+            type: object
+        type: object
+    served: true
+    storage: true
+    subresources:
+      status: {}
+---
+# Source: longhorn/templates/crds.yaml
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+  annotations:
+    controller-gen.kubebuilder.io/version: v0.19.0
+  labels:
+    app.kubernetes.io/name: longhorn
+    app.kubernetes.io/instance: longhorn
+    app.kubernetes.io/version: v1.9.0-dev
+    longhorn-manager: ""
+  name: systemrestores.longhorn.io
+spec:
+  group: longhorn.io
+  names:
+    kind: SystemRestore
+    listKind: SystemRestoreList
+    plural: systemrestores
+    shortNames:
+    - lhsr
+    singular: systemrestore
+  scope: Namespaced
+  versions:
+  - additionalPrinterColumns:
+    - description: The system restore state
+      jsonPath: .status.state
+      name: State
+      type: string
+    - jsonPath: .metadata.creationTimestamp
+      name: Age
+      type: date
+    name: v1beta2
+    schema:
+      openAPIV3Schema:
+        description: SystemRestore is where Longhorn stores system restore object
+        properties:
+          apiVersion:
+            description: |-
+              APIVersion defines the versioned schema of this representation of an object.
+              Servers should convert recognized schemas to the latest internal value, and
+              may reject unrecognized values.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+            type: string
+          kind:
+            description: |-
+              Kind is a string value representing the REST resource this object represents.
+              Servers may infer this from the endpoint the client submits requests to.
+              Cannot be updated.
+              In CamelCase.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+            type: string
+          metadata:
+            type: object
+          spec:
+            description: SystemRestoreSpec defines the desired state of the Longhorn
+              SystemRestore
+            properties:
+              systemBackup:
+                description: The system backup name in the object store.
+                type: string
+            required:
+            - systemBackup
+            type: object
+          status:
+            description: SystemRestoreStatus defines the observed state of the Longhorn
+              SystemRestore
+            properties:
+              conditions:
+                items:
+                  properties:
+                    lastProbeTime:
+                      description: Last time we probed the condition.
+                      type: string
+                    lastTransitionTime:
+                      description: Last time the condition transitioned from one status
+                        to another.
+                      type: string
+                    message:
+                      description: Human-readable message indicating details about
+                        last transition.
+                      type: string
+                    reason:
+                      description: Unique, one-word, CamelCase reason for the condition's
+                        last transition.
+                      type: string
+                    status:
+                      description: |-
+                        Status is the status of the condition.
+                        Can be True, False, Unknown.
+                      type: string
+                    type:
+                      description: Type is the type of the condition.
+                      type: string
+                  type: object
+                nullable: true
+                type: array
+              ownerID:
+                description: The node ID of the responsible controller to reconcile
+                  this SystemRestore.
+                type: string
+              sourceURL:
+                description: The source system backup URL.
+                type: string
+              state:
+                description: The system restore state.
+                type: string
+            type: object
+        type: object
+    served: true
+    storage: true
+    subresources:
+      status: {}
+---
+# Source: longhorn/templates/crds.yaml
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+  annotations:
+    controller-gen.kubebuilder.io/version: v0.19.0
+  labels:
+    app.kubernetes.io/name: longhorn
+    app.kubernetes.io/instance: longhorn
+    app.kubernetes.io/version: v1.9.0-dev
+    longhorn-manager: ""
+  name: volumeattachments.longhorn.io
+spec:
+  group: longhorn.io
+  names:
+    kind: VolumeAttachment
+    listKind: VolumeAttachmentList
+    plural: volumeattachments
+    shortNames:
+    - lhva
+    singular: volumeattachment
+  scope: Namespaced
+  versions:
+  - additionalPrinterColumns:
+    - jsonPath: .metadata.creationTimestamp
+      name: Age
+      type: date
+    name: v1beta2
+    schema:
+      openAPIV3Schema:
+        description: VolumeAttachment stores attachment information of a Longhorn
+          volume
+        properties:
+          apiVersion:
+            description: |-
+              APIVersion defines the versioned schema of this representation of an object.
+              Servers should convert recognized schemas to the latest internal value, and
+              may reject unrecognized values.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+            type: string
+          kind:
+            description: |-
+              Kind is a string value representing the REST resource this object represents.
+              Servers may infer this from the endpoint the client submits requests to.
+              Cannot be updated.
+              In CamelCase.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+            type: string
+          metadata:
+            type: object
+          spec:
+            description: VolumeAttachmentSpec defines the desired state of Longhorn
+              VolumeAttachment
+            properties:
+              attachmentTickets:
+                additionalProperties:
+                  properties:
+                    generation:
+                      description: |-
+                        A sequence number representing a specific generation of the desired state.
+                        Populated by the system. Read-only.
+                      format: int64
+                      type: integer
+                    id:
+                      description: The unique ID of this attachment. Used to differentiate
+                        different attachments of the same volume.
+                      type: string
+                    nodeID:
+                      description: The node that this attachment is requesting
+                      type: string
+                    parameters:
+                      additionalProperties:
+                        type: string
+                      description: Optional additional parameter for this attachment
+                      type: object
+                    type:
+                      type: string
+                  type: object
+                type: object
+              volume:
+                description: The name of Longhorn volume of this VolumeAttachment
+                type: string
+            required:
+            - volume
+            type: object
+          status:
+            description: VolumeAttachmentStatus defines the observed state of Longhorn
+              VolumeAttachment
+            properties:
+              attachmentTicketStatuses:
+                additionalProperties:
+                  properties:
+                    conditions:
+                      description: Record any error when trying to fulfill this attachment
+                      items:
+                        properties:
+                          lastProbeTime:
+                            description: Last time we probed the condition.
+                            type: string
+                          lastTransitionTime:
+                            description: Last time the condition transitioned from
+                              one status to another.
+                            type: string
+                          message:
+                            description: Human-readable message indicating details
+                              about last transition.
+                            type: string
+                          reason:
+                            description: Unique, one-word, CamelCase reason for the
+                              condition's last transition.
+                            type: string
+                          status:
+                            description: |-
+                              Status is the status of the condition.
+                              Can be True, False, Unknown.
+                            type: string
+                          type:
+                            description: Type is the type of the condition.
+                            type: string
+                        type: object
+                      nullable: true
+                      type: array
+                    generation:
+                      description: |-
+                        A sequence number representing a specific generation of the desired state.
+                        Populated by the system. Read-only.
+                      format: int64
+                      type: integer
+                    id:
+                      description: The unique ID of this attachment. Used to differentiate
+                        different attachments of the same volume.
+                      type: string
+                    satisfied:
+                      description: Indicate whether this attachment ticket has been
+                        satisfied
+                      type: boolean
+                  required:
+                  - conditions
+                  - satisfied
+                  type: object
+                type: object
+            type: object
+        type: object
+    served: true
+    storage: true
+    subresources:
+      status: {}
+---
+# Source: longhorn/templates/crds.yaml
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+  annotations:
+    controller-gen.kubebuilder.io/version: v0.19.0
+  labels:
+    app.kubernetes.io/name: longhorn
+    app.kubernetes.io/instance: longhorn
+    app.kubernetes.io/version: v1.9.0-dev
+    longhorn-manager: ""
+  name: volumes.longhorn.io
+spec:
+  group: longhorn.io
+  names:
+    kind: Volume
+    listKind: VolumeList
+    plural: volumes
+    shortNames:
+    - lhv
+    singular: volume
+  scope: Namespaced
+  versions:
+  - additionalPrinterColumns:
+    - description: The data engine of the volume
+      jsonPath: .spec.dataEngine
+      name: Data Engine
+      type: string
+    - description: The state of the volume
+      jsonPath: .status.state
+      name: State
+      type: string
+    - description: The robustness of the volume
+      jsonPath: .status.robustness
+      name: Robustness
+      type: string
+    - description: The scheduled condition of the volume
+      jsonPath: .status.conditions[?(@.type=='Schedulable')].status
+      name: Scheduled
+      type: string
+    - description: The size of the volume
+      jsonPath: .spec.size
+      name: Size
+      type: string
+    - description: The node that the volume is currently attaching to
+      jsonPath: .status.currentNodeID
+      name: Node
+      type: string
+    - jsonPath: .metadata.creationTimestamp
+      name: Age
+      type: date
+    name: v1beta2
+    schema:
+      openAPIV3Schema:
+        description: Volume is where Longhorn stores volume object.
+        properties:
+          apiVersion:
+            description: |-
+              APIVersion defines the versioned schema of this representation of an object.
+              Servers should convert recognized schemas to the latest internal value, and
+              may reject unrecognized values.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
+            type: string
+          kind:
+            description: |-
+              Kind is a string value representing the REST resource this object represents.
+              Servers may infer this from the endpoint the client submits requests to.
+              Cannot be updated.
+              In CamelCase.
+              More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
+            type: string
+          metadata:
+            type: object
+          spec:
+            description: VolumeSpec defines the desired state of the Longhorn volume
+            properties:
+              Standby:
+                type: boolean
+              accessMode:
+                enum:
+                - rwo
+                - rwop
+                - rwx
+                type: string
+              backingImage:
+                type: string
+                x-kubernetes-validations:
+                - message: BackingImage is immutable
+                  rule: self == oldSelf
+              backupBlockSize:
+                description: BackupBlockSize indicate the block size to create backups.
+                  The block size is immutable.
+                enum:
+                - "2097152"
+                - "16777216"
+                format: int64
+                type: string
+              backupCompressionMethod:
+                enum:
+                - none
+                - lz4
+                - gzip
+                type: string
+              backupTargetName:
+                description: The backup target name that the volume will be backed
+                  up to or is synced.
+                type: string
+              cloneMode:
+                enum:
+                - ""
+                - full-copy
+                - linked-clone
+                type: string
+              dataEngine:
+                enum:
+                - v1
+                - v2
+                type: string
+              dataLocality:
+                enum:
+                - disabled
+                - best-effort
+                - strict-local
+                type: string
+              dataSource:
+                type: string
+              disableFrontend:
+                type: boolean
+              diskSelector:
+                items:
+                  type: string
+                type: array
+              encrypted:
+                type: boolean
+                x-kubernetes-validations:
+                - message: Encrypted is immutable
+                  rule: self == oldSelf
+              freezeFilesystemForSnapshot:
+                description: Setting that freezes the filesystem on the root partition
+                  before a snapshot is created.
+                enum:
+                - ignored
+                - enabled
+                - disabled
+                type: string
+              fromBackup:
+                type: string
+              frontend:
+                enum:
+                - blockdev
+                - iscsi
+                - nvmf
+                - ublk
+                - ""
+                type: string
+              image:
+                type: string
+              lastAttachedBy:
+                type: string
+              migratable:
+                type: boolean
+              migrationNodeID:
+                type: string
+              nodeID:
+                type: string
+              nodeSelector:
+                items:
+                  type: string
+                type: array
+              numberOfReplicas:
+                type: integer
+              offlineRebuilding:
+                description: |-
+                  Specifies whether Longhorn should rebuild replicas while the detached volume is degraded.
+                  - ignored: Use the global setting for offline replica rebuilding.
+                  - enabled: Enable offline rebuilding for this volume, regardless of the global setting.
+                  - disabled: Disable offline rebuilding for this volume, regardless of the global setting
+                enum:
+                - ignored
+                - disabled
+                - enabled
+                type: string
+              rebuildConcurrentSyncLimit:
+                description: |-
+                  RebuildConcurrentSyncLimit controls the maximum number of file synchronization operations that can run
+                  concurrently during a single replica rebuild.
+                  When set to 0, it means following the global setting.
+                maximum: 5
+                minimum: 0
+                type: integer
+              replicaAutoBalance:
+                enum:
+                - ignored
+                - disabled
+                - least-effort
+                - best-effort
+                type: string
+              replicaDiskSoftAntiAffinity:
+                description: Replica disk soft anti affinity of the volume. Set enabled
+                  to allow replicas to be scheduled in the same disk.
+                enum:
+                - ignored
+                - enabled
+                - disabled
+                type: string
+              replicaRebuildingBandwidthLimit:
+                description: ReplicaRebuildingBandwidthLimit controls the maximum
+                  write bandwidth (in megabytes per second) allowed on the destination
+                  replica during the rebuilding process. Set this value to 0 to disable
+                  bandwidth limiting.
+                format: int64
+                minimum: 0
+                type: integer
+              replicaSoftAntiAffinity:
+                description: Replica soft anti affinity of the volume. Set enabled
+                  to allow replicas to be scheduled on the same node.
+                enum:
+                - ignored
+                - enabled
+                - disabled
+                type: string
+              replicaZoneSoftAntiAffinity:
+                description: Replica zone soft anti affinity of the volume. Set enabled
+                  to allow replicas to be scheduled in the same zone.
+                enum:
+                - ignored
+                - enabled
+                - disabled
+                type: string
+              restoreVolumeRecurringJob:
+                enum:
+                - ignored
+                - enabled
+                - disabled
+                type: string
+              revisionCounterDisabled:
+                type: boolean
+              size:
+                format: int64
+                type: string
+              snapshotDataIntegrity:
+                enum:
+                - ignored
+                - disabled
+                - enabled
+                - fast-check
+                type: string
+              snapshotMaxCount:
+                type: integer
+              snapshotMaxSize:
+                format: int64
+                type: string
+              staleReplicaTimeout:
+                type: integer
+              ublkNumberOfQueue:
+                description: ublkNumberOfQueue controls the number of queues for ublk
+                  frontend.
+                type: integer
+              ublkQueueDepth:
+                description: ublkQueueDepth controls the depth of each queue for ublk
+                  frontend.
+                type: integer
+              unmapMarkSnapChainRemoved:
+                enum:
+                - ignored
+                - disabled
+                - enabled
+                type: string
+            type: object
+          status:
+            description: VolumeStatus defines the observed state of the Longhorn volume
+            properties:
+              actualSize:
+                format: int64
+                type: integer
+              cloneStatus:
+                properties:
+                  attemptCount:
+                    type: integer
+                  nextAllowedAttemptAt:
+                    type: string
+                  snapshot:
+                    type: string
+                  sourceVolume:
+                    type: string
+                  state:
+                    type: string
+                type: object
+              conditions:
+                items:
+                  properties:
+                    lastProbeTime:
+                      description: Last time we probed the condition.
+                      type: string
+                    lastTransitionTime:
+                      description: Last time the condition transitioned from one status
+                        to another.
+                      type: string
+                    message:
+                      description: Human-readable message indicating details about
+                        last transition.
+                      type: string
+                    reason:
+                      description: Unique, one-word, CamelCase reason for the condition's
+                        last transition.
+                      type: string
+                    status:
+                      description: |-
+                        Status is the status of the condition.
+                        Can be True, False, Unknown.
+                      type: string
+                    type:
+                      description: Type is the type of the condition.
+                      type: string
+                  type: object
+                nullable: true
+                type: array
+              currentImage:
+                type: string
+              currentMigrationNodeID:
+                description: the node that this volume is currently migrating to
+                type: string
+              currentNodeID:
+                type: string
+              expansionRequired:
+                type: boolean
+              frontendDisabled:
+                type: boolean
+              isStandby:
+                type: boolean
+              kubernetesStatus:
+                properties:
+                  lastPVCRefAt:
+                    type: string
+                  lastPodRefAt:
+                    type: string
+                  namespace:
+                    description: determine if PVC/Namespace is history or not
+                    type: string
+                  pvName:
+                    type: string
+                  pvStatus:
+                    type: string
+                  pvcName:
+                    type: string
+                  workloadsStatus:
+                    description: determine if Pod/Workload is history or not
+                    items:
+                      properties:
+                        podName:
+                          type: string
+                        podStatus:
+                          type: string
+                        workloadName:
+                          type: string
+                        workloadType:
+                          type: string
+                      type: object
+                    nullable: true
+                    type: array
+                type: object
+              lastBackup:
+                type: string
+              lastBackupAt:
+                type: string
+              lastDegradedAt:
+                type: string
+              ownerID:
+                type: string
+              remountRequestedAt:
+                type: string
+              restoreInitiated:
+                type: boolean
+              restoreRequired:
+                type: boolean
+              robustness:
+                type: string
+              shareEndpoint:
+                type: string
+              shareState:
+                type: string
+              state:
+                type: string
+            type: object
+        type: object
+    served: true
+    storage: true
+    subresources:
+      status: {}
+---
+# Source: longhorn/templates/clusterrole.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: longhorn-role
+  labels:
+    app.kubernetes.io/name: longhorn
+    app.kubernetes.io/instance: longhorn
+    app.kubernetes.io/version: v1.9.0-dev
+rules:
+- apiGroups:
+  - apiextensions.k8s.io
+  resources:
+  - customresourcedefinitions
+  verbs:
+  - "*"
+- apiGroups: [""]
+  resources: ["pods"]
+  verbs: ["get", "list", "watch", "delete", "deletecollection"]
+- apiGroups: [""]
+  resources: ["secrets", "services", "endpoints", "configmaps", "serviceaccounts", "pods/log"]
+  verbs: ["get", "list", "watch"]
+- apiGroups: [""]
+  resources: ["events", "persistentvolumes", "persistentvolumeclaims", "persistentvolumeclaims/status", "nodes"]
+  verbs: ["*"]
+- apiGroups: [""]
+  resources: ["namespaces"]
+  verbs: ["get", "list"]
+- apiGroups: ["apps"]
+  resources: ["daemonsets", "statefulsets", "deployments", "replicasets"]
+  verbs: ["get", "list", "watch"]
+- apiGroups: ["batch"]
+  resources: ["jobs", "cronjobs"]
+  verbs: ["get", "list", "watch"]
+- apiGroups: ["policy"]
+  resources: ["poddisruptionbudgets"]
+  verbs: ["get", "list", "watch"]
+- apiGroups: ["scheduling.k8s.io"]
+  resources: ["priorityclasses"]
+  verbs: ["watch", "list"]
+- apiGroups: ["storage.k8s.io"]
+  resources: ["storageclasses", "volumeattachments", "volumeattachments/status", "csinodes", "csidrivers", "csistoragecapacities"]
+  verbs: ["*"]
+- apiGroups: ["snapshot.storage.k8s.io"]
+  resources: ["volumesnapshotclasses", "volumesnapshots", "volumesnapshotcontents", "volumesnapshotcontents/status"]
+  verbs: ["*"]
+- apiGroups: ["longhorn.io"]
+  resources: ["volumes", "volumes/status", "engines", "engines/status", "replicas", "replicas/status", "settings", "settings/status",
+              "engineimages", "engineimages/status", "nodes", "nodes/status", "instancemanagers", "instancemanagers/status",
+              "sharemanagers", "sharemanagers/status", "backingimages", "backingimages/status",
+              "backingimagemanagers", "backingimagemanagers/status", "backingimagedatasources", "backingimagedatasources/status",
+              "backuptargets", "backuptargets/status", "backupvolumes", "backupvolumes/status", "backups", "backups/status",
+              "recurringjobs", "recurringjobs/status", "orphans", "orphans/status", "snapshots", "snapshots/status",
+              "supportbundles", "supportbundles/status", "systembackups", "systembackups/status", "systemrestores", "systemrestores/status",
+              "volumeattachments", "volumeattachments/status", "backupbackingimages", "backupbackingimages/status"]
+  verbs: ["*"]
+- apiGroups: ["coordination.k8s.io"]
+  resources: ["leases"]
+  verbs: ["get", "list", "watch"]
+- apiGroups: ["metrics.k8s.io"]
+  resources: ["pods", "nodes"]
+  verbs: ["get", "list"]
+- apiGroups: ["apiregistration.k8s.io"]
+  resources: ["apiservices"]
+  verbs: ["list", "watch"]
+- apiGroups: ["admissionregistration.k8s.io"]
+  resources: ["mutatingwebhookconfigurations", "validatingwebhookconfigurations"]
+  verbs: ["get", "list", "create", "patch", "delete"]
+- apiGroups: ["rbac.authorization.k8s.io"]
+  resources: ["roles", "rolebindings"]
+  verbs: ["get", "list", "watch"]
+- apiGroups: ["discovery.k8s.io"]
+  resources: ["endpointslices"]
+  verbs: ["get", "list", "watch"]
+- apiGroups: ["rbac.authorization.k8s.io"]
+  resources: ["clusterrolebindings", "clusterroles"]
+  verbs: ["*"]
+---
+# Source: longhorn/templates/clusterrolebinding.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: longhorn-bind
+  labels:
+    app.kubernetes.io/name: longhorn
+    app.kubernetes.io/instance: longhorn
+    app.kubernetes.io/version: v1.9.0-dev
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: longhorn-role
+subjects:
+- kind: ServiceAccount
+  name: longhorn-service-account
+  namespace: longhorn-system
+---
+# Source: longhorn/templates/clusterrolebinding.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: longhorn-support-bundle
+  labels:
+    app.kubernetes.io/name: longhorn
+    app.kubernetes.io/instance: longhorn
+    app.kubernetes.io/version: v1.9.0-dev
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: cluster-admin
+subjects:
+- kind: ServiceAccount
+  name: longhorn-support-bundle
+  namespace: longhorn-system
+---
+# Source: longhorn/templates/role.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: longhorn
+  namespace: longhorn-system
+  labels:
+    app.kubernetes.io/name: longhorn
+    app.kubernetes.io/instance: longhorn
+    app.kubernetes.io/version: v1.9.0-dev
+rules:
+- apiGroups: [""]
+  resources: ["pods", "pods/log", "events", "secrets", "services", "endpoints", "configmaps", "serviceaccounts", "persistentvolumeclaims", "persistentvolumeclaims/status"]
+  verbs: ["*"]
+- apiGroups: ["apps"]
+  resources: ["daemonsets", "deployments", "statefulsets", "replicasets"]
+  verbs: ["*"]
+- apiGroups: ["batch"]
+  resources: ["jobs", "cronjobs"]
+  verbs: ["*"]
+- apiGroups: ["policy"]
+  resources: ["poddisruptionbudgets"]
+  verbs: ["*"]
+- apiGroups: ["coordination.k8s.io"]
+  resources: ["leases"]
+  verbs: ["*"]
+- apiGroups: ["rbac.authorization.k8s.io"]
+  resources: ["roles", "rolebindings"]
+  verbs: ["*"]
+- apiGroups: ["discovery.k8s.io"]
+  resources: ["endpointslices"]
+  verbs: ["*"]
+---
+# Source: longhorn/templates/rolebinding.yaml
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: longhorn
+  namespace: longhorn-system
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: Role
+  name: longhorn
+subjects:
+- kind: ServiceAccount
+  name: longhorn-service-account
+  namespace: longhorn-system
+---
+# Source: longhorn/templates/daemonset-sa.yaml
+apiVersion: v1
+kind: Service
+metadata:
+  labels:
+    app.kubernetes.io/name: longhorn
+    app.kubernetes.io/instance: longhorn
+    app.kubernetes.io/version: v1.9.0-dev
+    app: longhorn-manager
+  name: longhorn-backend
+  namespace: longhorn-system
+spec:
+  type: ClusterIP
+  selector:
+    app: longhorn-manager
+  ports:
+  - name: manager
+    port: 9500
+    targetPort: manager
+---
+# Source: longhorn/templates/deployment-ui.yaml
+kind: Service
+apiVersion: v1
+metadata:
+  labels:
+    app.kubernetes.io/name: longhorn
+    app.kubernetes.io/instance: longhorn
+    app.kubernetes.io/version: v1.9.0-dev
+    app: longhorn-ui
+  name: longhorn-frontend
+  namespace: longhorn-system
+spec:
+  type: ClusterIP
+  selector:
+    app: longhorn-ui
+  ports:
+  - name: http
+    port: 80
+    targetPort: http
+    nodePort: null
+---
+# Source: longhorn/templates/services.yaml
+apiVersion: v1
+kind: Service
+metadata:
+  labels:
+    app.kubernetes.io/name: longhorn
+    app.kubernetes.io/instance: longhorn
+    app.kubernetes.io/version: v1.9.0-dev
+    app: longhorn-admission-webhook
+  name: longhorn-admission-webhook
+  namespace: longhorn-system
+spec:
+  type: ClusterIP
+  selector:
+    longhorn.io/admission-webhook: longhorn-admission-webhook
+  ports:
+  - name: admission-webhook
+    port: 9502
+    targetPort: admission-wh
+---
+# Source: longhorn/templates/services.yaml
+apiVersion: v1
+kind: Service
+metadata:
+  labels:
+    app.kubernetes.io/name: longhorn
+    app.kubernetes.io/instance: longhorn
+    app.kubernetes.io/version: v1.9.0-dev
+    app: longhorn-recovery-backend
+  name: longhorn-recovery-backend
+  namespace: longhorn-system
+spec:
+  type: ClusterIP
+  selector:
+    longhorn.io/recovery-backend: longhorn-recovery-backend
+  ports:
+  - name: recovery-backend
+    port: 9503
+    targetPort: recov-backend
+---
+# Source: longhorn/templates/daemonset-sa.yaml
+apiVersion: apps/v1
+kind: DaemonSet
+metadata:
+  labels:
+    app.kubernetes.io/name: longhorn
+    app.kubernetes.io/instance: longhorn
+    app.kubernetes.io/version: v1.9.0-dev
+    app: longhorn-manager
+  name: longhorn-manager
+  namespace: longhorn-system
+spec:
+  selector:
+    matchLabels:
+      app: longhorn-manager
+  template:
+    metadata:
+      labels:
+        app.kubernetes.io/name: longhorn
+        app.kubernetes.io/instance: longhorn
+        app.kubernetes.io/version: v1.9.0-dev
+        app: longhorn-manager
+    spec:
+      containers:
+      - name: longhorn-manager
+        image: docker.io/longhornio/longhorn-manager:master-head
+        imagePullPolicy: IfNotPresent
+        securityContext:
+          privileged: true
+        command:
+        - longhorn-manager
+        - -d
+        - daemon
+        - --engine-image
+        - "docker.io/longhornio/longhorn-engine:master-head"
+        - --instance-manager-image
+        - "docker.io/longhornio/longhorn-instance-manager:master-head"
+        - --share-manager-image
+        - "docker.io/longhornio/longhorn-share-manager:master-head"
+        - --backing-image-manager-image
+        - "docker.io/longhornio/backing-image-manager:master-head"
+        - --support-bundle-manager-image
+        - "docker.io/longhornio/support-bundle-kit:v0.0.78"
+        - --manager-image
+        - "docker.io/longhornio/longhorn-manager:master-head"
+        - --service-account
+        - longhorn-service-account
+        - --upgrade-version-check
+        ports:
+        - containerPort: 9500
+          name: manager
+        - containerPort: 9502
+          name: admission-wh
+        - containerPort: 9503
+          name: recov-backend
+        readinessProbe:
+          httpGet:
+            path: /v1/healthz
+            port: 9502
+            scheme: HTTPS
+        volumeMounts:
+        - name: boot
+          mountPath: /host/boot/
+          readOnly: true
+        - name: dev
+          mountPath: /host/dev/
+        - name: proc
+          mountPath: /host/proc/
+          readOnly: true
+        - name: etc
+          mountPath: /host/etc/
+          readOnly: true
+        - name: longhorn
+          mountPath: /var/lib/longhorn/
+          mountPropagation: Bidirectional
+        - name: longhorn-grpc-tls
+          mountPath: /tls-files/
+        env:
+        - name: POD_NAME
+          valueFrom:
+            fieldRef:
+              fieldPath: metadata.name
+        - name: POD_NAMESPACE
+          valueFrom:
+            fieldRef:
+              fieldPath: metadata.namespace
+        - name: POD_IP
+          valueFrom:
+            fieldRef:
+              fieldPath: status.podIP
+        - name: NODE_NAME
+          valueFrom:
+            fieldRef:
+              fieldPath: spec.nodeName
+        
+      - name: pre-pull-share-manager-image
+        imagePullPolicy: IfNotPresent
+        image: docker.io/longhornio/longhorn-share-manager:master-head
+        command: ["sh", "-c", "echo share-manager image pulled && sleep infinity"]
+      volumes:
+      - name: boot
+        hostPath:
+          path: /boot/
+      - name: dev
+        hostPath:
+          path: /dev/
+      - name: proc
+        hostPath:
+          path: /proc/
+      - name: etc
+        hostPath:
+          path: /etc/
+      - name: longhorn
+        hostPath:
+          path: /var/lib/longhorn/
+      - name: longhorn-grpc-tls
+        secret:
+          secretName: longhorn-grpc-tls
+          optional: true
+      priorityClassName: "longhorn-critical"
+      serviceAccountName: longhorn-service-account
+  updateStrategy:
+    rollingUpdate:
+      maxUnavailable: 100%
+---
+# Source: longhorn/templates/deployment-driver.yaml
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: longhorn-driver-deployer
+  namespace: longhorn-system
+  labels:
+    app.kubernetes.io/name: longhorn
+    app.kubernetes.io/instance: longhorn
+    app.kubernetes.io/version: v1.9.0-dev
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: longhorn-driver-deployer
+  template:
+    metadata:
+      labels:
+        app.kubernetes.io/name: longhorn
+        app.kubernetes.io/instance: longhorn
+        app.kubernetes.io/version: v1.9.0-dev
+        app: longhorn-driver-deployer
+    spec:
+      initContainers:
+        - name: wait-longhorn-manager
+          image: docker.io/longhornio/longhorn-manager:master-head
+          command: ['sh', '-c', 'while [ $(curl -m 1 -s -o /dev/null -w "%{http_code}" http://longhorn-backend:9500/v1) != "200" ]; do echo waiting; sleep 2; done']
+      containers:
+        - name: longhorn-driver-deployer
+          image: docker.io/longhornio/longhorn-manager:master-head
+          imagePullPolicy: IfNotPresent
+          command:
+          - longhorn-manager
+          - -d
+          - deploy-driver
+          - --manager-image
+          - "docker.io/longhornio/longhorn-manager:master-head"
+          - --manager-url
+          - http://longhorn-backend:9500/v1
+          env:
+          - name: POD_NAMESPACE
+            valueFrom:
+              fieldRef:
+                fieldPath: metadata.namespace
+          - name: NODE_NAME
+            valueFrom:
+              fieldRef:
+                fieldPath: spec.nodeName
+          - name: SERVICE_ACCOUNT
+            valueFrom:
+              fieldRef:
+                fieldPath: spec.serviceAccountName
+          - name: CSI_ATTACHER_IMAGE
+            value: "docker.io/longhornio/csi-attacher:v4.10.0-20251226"
+          - name: CSI_PROVISIONER_IMAGE
+            value: "docker.io/longhornio/csi-provisioner:v5.3.0-20251226"
+          - name: CSI_NODE_DRIVER_REGISTRAR_IMAGE
+            value: "docker.io/longhornio/csi-node-driver-registrar:v2.15.0-20251226"
+          - name: CSI_RESIZER_IMAGE
+            value: "docker.io/longhornio/csi-resizer:v2.0.0-20251226"
+          - name: CSI_SNAPSHOTTER_IMAGE
+            value: "docker.io/longhornio/csi-snapshotter:v8.4.0-20251226"
+          - name: CSI_LIVENESS_PROBE_IMAGE
+            value: "docker.io/longhornio/livenessprobe:v2.17.0-20251226"
+          
+      priorityClassName: "longhorn-critical"
+      serviceAccountName: longhorn-service-account
+      securityContext:
+        runAsUser: 0
+---
+# Source: longhorn/templates/deployment-ui.yaml
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  labels:
+    app.kubernetes.io/name: longhorn
+    app.kubernetes.io/instance: longhorn
+    app.kubernetes.io/version: v1.9.0-dev
+    app: longhorn-ui
+  name: longhorn-ui
+  namespace: longhorn-system
+spec:
+  replicas: 2
+  selector:
+    matchLabels:
+      app: longhorn-ui
+  template:
+    metadata:
+      labels:
+        app.kubernetes.io/name: longhorn
+        app.kubernetes.io/instance: longhorn
+        app.kubernetes.io/version: v1.9.0-dev
+        app: longhorn-ui
+    spec:
+      serviceAccountName: longhorn-ui-service-account
+      affinity:
+        podAntiAffinity:
+          preferredDuringSchedulingIgnoredDuringExecution:
+          - podAffinityTerm:
+              labelSelector:
+                matchExpressions:
+                - key: app
+                  operator: In
+                  values:
+                  - longhorn-ui
+              topologyKey: kubernetes.io/hostname
+            weight: 1
+      containers:
+      - name: longhorn-ui
+        image: docker.io/longhornio/longhorn-ui:master-head
+        imagePullPolicy: IfNotPresent
+        volumeMounts:
+        - name: nginx-cache
+          mountPath: /var/cache/nginx/
+        - name: nginx-config
+          mountPath: /var/config/nginx/
+        - name: var-run
+          mountPath: /var/run/
+        ports:
+        - containerPort: 8000
+          name: http
+        env:
+          - name: LONGHORN_MANAGER_IP
+            value: "http://longhorn-backend:9500"
+          - name: LONGHORN_UI_PORT
+            value: "8000"
+          
+      volumes:
+      - emptyDir: {}
+        name: nginx-cache
+      - emptyDir: {}
+        name: nginx-config
+      - emptyDir: {}
+        name: var-run
+      priorityClassName: "longhorn-critical"
+---
+# Source: longhorn/templates/validate-psp-install.yaml
+#

+ 5 - 0
Postgres/Longhorn/setup.sh

@@ -0,0 +1,5 @@
+kubectl apply -f https://raw.githubusercontent.com/longhorn/longhorn/master/deploy/longhorn.yaml
+
+kubectl -n longhorn-system get pods
+
+kubectl get storageclass

+ 20 - 0
Postgres/postgres-cluster.yaml

@@ -0,0 +1,20 @@
+apiVersion: postgresql.cnpg.io/v1
+kind: Cluster
+metadata:
+  name: postgres
+spec:
+  instances: 3
+
+  storage:
+    size: 20Gi
+    storageClass: longhorn
+
+  superuserSecret:
+    name: postgres-superuser
+
+  bootstrap:
+    initdb:
+      database: appdb
+      owner: appuser
+      secret:
+        name: appuser-secret

+ 12 - 0
Postgres/postgres-loadbalancer.yaml

@@ -0,0 +1,12 @@
+apiVersion: v1
+kind: Service
+metadata:
+  name: postgres-lb
+spec:
+  type: LoadBalancer
+  selector:
+    cnpg.io/cluster: postgres
+    role: primary
+  ports:
+  - port: 5432
+    targetPort: 5432

+ 16 - 0
Postgres/postgres-secrets.yaml

@@ -0,0 +1,16 @@
+apiVersion: v1
+kind: Secret
+metadata:
+  name: postgres-superuser
+type: Opaque
+stringData:
+  password: supersecretpassword
+---
+apiVersion: v1
+kind: Secret
+metadata:
+  name: appuser-secret
+type: Opaque
+stringData:
+  username: appuser
+  password: apppassword

+ 10 - 0
Postgres/setup-postgres.sh

@@ -0,0 +1,10 @@
+kubectl apply --server-side -f \
+  https://raw.githubusercontent.com/cloudnative-pg/cloudnative-pg/release-1.23/releases/cnpg-1.23.0.yaml
+
+kubectl get pods -n cnpg-system
+
+kubectl apply -f postgres-secrets.yaml
+kubectl apply -f postgres-cluster.yaml
+
+kubectl apply -f postgres-loadbalancer.yaml
+

+ 7 - 0
arcadis/Chart.yaml

@@ -0,0 +1,7 @@
+apiVersion: v2
+name: arcadis-web
+version: 0.1.0
+appversion: "2"
+description: Arcadis website
+
+dependencies: []

+ 15 - 0
arcadis/certificate-arcadis.yaml

@@ -0,0 +1,15 @@
+# certificate.yaml
+apiVersion: cert-manager.io/v1
+kind: Certificate
+metadata:
+  name: arcadis-cert-secret
+  namespace: arcadis
+spec:
+  secretName: arcadis-cert-secret
+  issuerRef:
+    name: letsencrypt-prod
+    kind: ClusterIssuer
+  commonName: www.arcadis.is
+  dnsNames:
+    - www.arcadis.is
+    - arcadis.is

+ 6 - 0
arcadis/deploy.sh

@@ -0,0 +1,6 @@
+
+kubectl create namespace arcadis
+
+
+helm install arcadis-web . -n arcadis 
+

+ 34 - 0
arcadis/deployment.yaml

@@ -0,0 +1,34 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: arcadis-web
+  namespace: arcadis
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: arcadis-web
+  template:
+    metadata:
+      labels:
+        app: arcadis-web
+    spec:
+      containers:
+      - name: arcadis-web
+        image: registry.asterisk.is/arcadis-web:nginx-v2
+        ports:
+        - containerPort: 80
+      imagePullSecrets:
+        - name: registry-asterisk-is
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: arcadis-web
+  namespace: arcadis
+spec:
+  selector:
+    app: arcadis-web
+  ports:
+  - port: 80
+    targetPort: 80

+ 36 - 0
arcadis/ingress.yaml

@@ -0,0 +1,36 @@
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+  name: arcadis-ingress
+  namespace: arcadis
+  annotations:
+    kubernetes.io/ingress.class: "traefik"
+    cert-manager.io/cluster-issuer: "letsencrypt-prod"
+spec:
+  tls:
+  - hosts:
+    - www.arcadis.is
+    - arcadis.is
+    secretName: arcadis-cert-secret
+  ingressClassName: traefik
+  rules:
+  - host: www.arcadis.is
+    http:
+      paths:
+      - path: /
+        pathType: Prefix
+        backend:
+          service:
+            name: arcadis-web
+            port:
+              number: 80
+  - host: arcadis.is
+    http:
+      paths:
+      - path: /
+        pathType: Prefix
+        backend:
+          service:
+            name: arcadis-web
+            port:
+              number: 80

+ 4 - 0
arcadis/namespace.yaml

@@ -0,0 +1,4 @@
+apiVersion: v1
+kind: Namespace
+metadata:
+  name: arcadis

+ 18 - 0
arcadis/templates/_helpers.tpl

@@ -0,0 +1,18 @@
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "arcadis-web.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end }}
+
+{{/*
+Create a fullname using the release name.
+*/}}
+{{- define "arcadis-web.fullname" -}}
+{{- if .Values.fullnameOverride }}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
+{{- else }}
+{{- $name := default .Chart.Name .Values.nameOverride }}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
+{{- end }}
+{{- end }}

+ 27 - 0
arcadis/templates/certificate.yaml

@@ -0,0 +1,27 @@
+apiVersion: cert-manager.io/v1
+kind: Certificate
+metadata:
+  name: {{ .Values.application.tls.certSecretName }}
+spec:
+  secretName: {{ .Values.application.tls.certSecretName }}
+  dnsNames:
+  - {{ .Values.ingress.host }}
+  issuerRef:
+    name: {{ .Values.ingress.tls.issuerRef.name }}
+    kind: {{ .Values.ingress.tls.issuerRef.kind }}
+
+# certificate.yaml
+apiVersion: cert-manager.io/v1
+kind: Certificate
+metadata:
+  name: arcadis-cert-secret
+  namespace: arcadis
+spec:
+  secretName: arcadis-cert-secret
+  issuerRef:
+    name: letsencrypt-prod
+    kind: ClusterIssuer
+  commonName: www.arcadis.is
+  dnsNames:
+    - www.arcadis.is
+    - arcadis.is

+ 45 - 0
arcadis/templates/deployment.yaml

@@ -0,0 +1,45 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: {{ include "asterisk-registry.fullname" . }}
+  labels:
+    app: {{ include "asterisk-registry.name" . }}
+spec:
+  replicas: {{ .Values.replicaCount }}
+  selector:
+    matchLabels:
+      app: {{ include "asterisk-registry.name" . }}
+  template:
+    metadata:
+      labels:
+        app: {{ include "asterisk-registry.name" . }}
+    spec:
+      containers:
+      - name: registry
+        image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
+        imagePullPolicy: {{ .Values.image.pullPolicy }}
+        ports:
+        - containerPort: 5000
+        env:
+        - name: REGISTRY_HTTP_SECRET
+          value: super-secret-string
+        - name: REGISTRY_AUTH
+          value: htpasswd
+        - name: REGISTRY_AUTH_HTPASSWD_REALM
+          value: Registry Realm
+        - name: REGISTRY_AUTH_HTPASSWD_PATH
+          value: /auth/htpasswd
+        volumeMounts:
+        - name: registry-storage
+          mountPath: /var/lib/registry
+        - name: auth
+          mountPath: /auth
+      volumes:
+      - name: registry-storage
+        persistentVolumeClaim:
+          claimName: {{ include "asterisk-registry.fullname" . }}-pvc
+      - name: auth
+        secret:
+          secretName: registry-htpasswd
+
+      

+ 34 - 0
arcadis/templates/ingress.yaml

@@ -0,0 +1,34 @@
+{{- if .Values.ingress.enabled }}
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+  name: {{ include "asterisk-registry.fullname" . }}-ingress
+  annotations:
+    nginx.ingress.kubernetes.io/proxy-body-size: "0"
+    #nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
+    #nginx.ingress.kubernetes.io/ssl-redirect: "true"
+    #nginx.ingress.kubernetes.io/secure-backends: "true"
+    cert-manager.io/http01-edit-in-place: "true"
+    {{- if .Values.ingress.tls.enabled }}
+    cert-manager.io/cluster-issuer: "{{ .Values.ingress.tls.issuerRef.name }}"
+    {{- end }}
+spec:
+  ingressClassName: {{ .Values.ingress.className }}
+  {{- if .Values.ingress.tls.enabled }}
+  tls:
+    - hosts:
+        - {{ .Values.ingress.host }}
+      secretName: {{ .Values.ingress.tls.secretName }}
+  {{- end }}
+  rules:
+    - host: {{ .Values.ingress.host }}
+      http:
+        paths:
+          - path: /
+            pathType: Prefix
+            backend:
+              service:
+                name: {{ include "asterisk-registry.fullname" . }}
+                port:
+                  number: {{ .Values.service.port }}
+{{- end }}

+ 14 - 0
arcadis/templates/issuer-prod.yaml

@@ -0,0 +1,14 @@
+apiVersion: cert-manager.io/v1
+kind: Issuer
+metadata:
+  name: letsencrypt-prod
+spec:
+  acme:
+    server: https://acme-v02.api.letsencrypt.org/directory
+    email: [email protected]
+    privateKeySecretRef:
+      name: letsencrypt-prod
+    solvers:
+    - http01:
+        ingress:
+          class: nginx

+ 14 - 0
arcadis/templates/issuer.yaml

@@ -0,0 +1,14 @@
+apiVersion: cert-manager.io/v1
+kind: Issuer
+metadata:
+  name: letsencrypt-staging
+spec:
+  acme:
+    server: https://acme-staging-v02.api.letsencrypt.org/directory
+    email: [email protected]
+    privateKeySecretRef:
+      name: letsencrypt-staging
+    solvers:
+    - http01:
+        ingress:
+          class: nginx

+ 13 - 0
arcadis/templates/service.yaml

@@ -0,0 +1,13 @@
+apiVersion: v1
+kind: Service
+metadata:
+  name: {{ include "asterisk-registry.fullname" . }}
+spec:
+  type: {{ .Values.service.type }}
+  selector:
+    app: {{ include "asterisk-registry.name" . }}
+  ports:
+    - port: {{ .Values.service.port }}
+      targetPort: 5000
+      protocol: TCP
+

+ 34 - 0
arcadis/test.yaml

@@ -0,0 +1,34 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: hello-kubernetes
+  namespace: arcadis
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: hello-kubernetes
+  template:
+    metadata:
+      labels:
+        app: hello-kubernetes
+    spec:
+      containers:
+      - name: hello-kubernetes
+        image: hashicorp/http-echo
+        args:
+        - "-text=Arca"
+        ports:
+        - containerPort: 5678
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: hello-kubernetes
+  namespace: arcadis
+spec:
+  selector:
+    app: hello-kubernetes
+  ports:
+  - port: 80
+    targetPort: 5678

+ 36 - 0
arcadis/values.yaml

@@ -0,0 +1,36 @@
+replicaCount: 1
+image:
+  repository: registry
+  tag: "2"
+  pullPolicy: IfNotPresent
+
+service:
+  type: ClusterIP
+  port: 5000
+
+storage:
+  size: 5Gi
+  className: ""
+
+#persistence:
+#  enabled: true
+#  size: 1Gi
+#  path: /mnt/data/registry
+
+application:
+  tls:
+    enabled: true
+    certSecretName: arcadis-cert-secret
+    certFile: tls.crt
+    keyFile: tls.key
+
+ingress:
+  enabled: true
+  className: traefik
+  host: registry.asterisk.is
+  tls:
+    enabled: true
+    secretName: registry-tls
+    issuerRef:
+      name: letsencrypt-prod
+      kind: ClusterIssuer

+ 14 - 0
cert-manager/certificate-irdi-eu.yaml

@@ -0,0 +1,14 @@
+# certificate.yaml
+apiVersion: cert-manager.io/v1
+kind: Certificate
+metadata:
+  name: irdi-cert
+  namespace: default
+spec:
+  secretName: irdi-cert-secret
+  issuerRef:
+    name: letsencrypt-staging
+    kind: ClusterIssuer
+  commonName: www.irdi.eu
+  dnsNames:
+    - www.irdi.eu

+ 15 - 0
cert-manager/cluster-issuer-prod.yaml

@@ -0,0 +1,15 @@
+# cluster-issuer-staging.yaml
+apiVersion: cert-manager.io/v1
+kind: ClusterIssuer
+metadata:
+  name: letsencrypt-prod
+spec:
+  acme:
+    server: https://acme-v02.api.letsencrypt.org/directory
+    email: [email protected]
+    privateKeySecretRef:
+      name: letsencrypt-prod
+    solvers:
+    - http01:
+        ingress:
+          ingressClassName: nginx

+ 15 - 0
cert-manager/cluster-issuer-staging.yaml

@@ -0,0 +1,15 @@
+# cluster-issuer-staging.yaml
+apiVersion: cert-manager.io/v1
+kind: ClusterIssuer
+metadata:
+  name: letsencrypt-staging
+spec:
+  acme:
+    server: https://acme-staging-v02.api.letsencrypt.org/directory
+    email: [email protected]
+    privateKeySecretRef:
+      name: letsencrypt-staging
+    solvers:
+    - http01:
+        ingress:
+          ingressClassName: nginx

+ 27 - 0
cert-manager/setup.sh

@@ -0,0 +1,27 @@
+#kubectl apply -f https://github.com/cert-manager/cert-manager/releases/latest/download/cert-manager.yaml
+
+#kubectl get pods --namespace cert-manager
+
+#helm install \
+#  cert-manager oci://quay.io/jetstack/charts/cert-manager \
+#  --version v1.18.2 \
+#  --namespace cert-manager \
+#  --create-namespace \
+#  --set crds.enabled=true
+
+kubectl apply -f - <<EOF
+apiVersion: cert-manager.io/v1
+kind: ClusterIssuer
+metadata:
+  name: letsencrypt-prod
+spec:
+  acme:
+    server: https://acme-v02.api.letsencrypt.org/directory
+    email: [email protected]
+    privateKeySecretRef:
+      name: letsencrypt-prod
+    solvers:
+    - http01:
+        ingress:
+          class: nginx
+EOF

+ 39 - 0
gogs/deployment.yaml

@@ -0,0 +1,39 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: gogs
+  namespace: git
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: gogs
+  template:
+    metadata:
+      labels:
+        app: gogs
+    spec:
+      containers:
+        - name: gogs
+          image: gogs/gogs:latest
+          ports:
+            - containerPort: 3000
+            - containerPort: 22
+          env:
+            - name: DB_TYPE
+              value: postgres
+            - name: DB_HOST
+              value: postgres.default.svc.cluster.local:5432
+            - name: DB_NAME
+              value: gogs
+            - name: DB_USER
+              value: gogs
+            - name: DB_PASSWD
+              value: strongpassword
+          volumeMounts:
+            - name: gogs-data
+              mountPath: /data
+      volumes:
+        - name: gogs-data
+          persistentVolumeClaim:
+            claimName: gogs-data

+ 25 - 0
gogs/ingress.yaml

@@ -0,0 +1,25 @@
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+  name: gogs
+  namespace: git
+  annotations:
+    kubernetes.io/ingress.class: "traefik"
+    cert-manager.io/cluster-issuer: letsencrypt-prod
+    traefik.ingress.kubernetes.io/router.entrypoints: websecure
+spec:
+  tls:
+    - hosts:
+        - git.irdi.eu
+      secretName: gogs-tls
+  rules:
+    - host: git.irdi.eu
+      http:
+        paths:
+          - path: /
+            pathType: Prefix
+            backend:
+              service:
+                name: gogs
+                port:
+                  number: 3000

+ 12 - 0
gogs/pvc.yaml

@@ -0,0 +1,12 @@
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+  name: gogs-data
+  namespace: git
+spec:
+  accessModes:
+    - ReadWriteOnce
+  storageClassName: longhorn
+  resources:
+    requests:
+      storage: 10Gi

+ 14 - 0
gogs/service-ssh.yaml

@@ -0,0 +1,14 @@
+apiVersion: v1
+kind: Service
+metadata:
+  name: gogs-ssh
+  namespace: git
+spec:
+  type: LoadBalancer  # Use NodePort if you don't have a LoadBalancer
+  selector:
+    app: gogs
+  ports:
+    - name: ssh
+      port: 22
+      targetPort: 22
+      # nodePort: 30022  # Uncomment if using NodePort

+ 16 - 0
gogs/service.yaml

@@ -0,0 +1,16 @@
+apiVersion: v1
+kind: Service
+metadata:
+  name: gogs
+  namespace: git
+spec:
+  type: ClusterIP
+  selector:
+    app: gogs
+  ports:
+    - name: http
+      port: 3000
+      targetPort: 3000
+    - name: ssh
+      port: 22
+      targetPort: 22

+ 8 - 0
gogs/setup.sh

@@ -0,0 +1,8 @@
+kubectl create namespace git
+
+kubectl apply -f pvc.yaml
+kubectl apply -f deployment.yaml
+kubectl apply -f service.yaml
+kubectl apply -f ingress.yaml
+
+https://chatgpt.com/share/696ffc62-2c34-8002-81c4-98f988425f01

+ 5 - 0
metallb/advertisement.yaml

@@ -0,0 +1,5 @@
+apiVersion: metallb.io/v1beta1
+kind: L2Advertisement
+metadata:
+  name: l2-advertisement
+  namespace: metallb-system

+ 8 - 0
metallb/ippool.yaml

@@ -0,0 +1,8 @@
+apiVersion: metallb.io/v1beta1
+kind: IPAddressPool
+metadata:
+  name: k3s-ip-pool
+  namespace: metallb-system
+spec:
+  addresses:
+  - 192.168.1.241-192.168.1.250

+ 1 - 0
metallb/setup-metallb.sh

@@ -0,0 +1 @@
+kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.13.7/config/manifests/metallb-native.yaml

+ 6 - 0
rabbitmq-chart/Chart.yaml

@@ -0,0 +1,6 @@
+apiVersion: v2
+name: rabbitmq-chart
+description: "RabbitMQ Helm chart for k3s on 3-node Raspberry Pi cluster"
+type: application
+version: 0.1.0
+appVersion: "3.9"

+ 13 - 0
rabbitmq-chart/install.sh

@@ -0,0 +1,13 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+RELEASE=${RELEASE:-rabbitmq}
+NAMESPACE=${NAMESPACE:-rabbitmq}
+CHART_DIR=$(dirname "${BASH_SOURCE[0]}")
+
+echo "Installing release '$RELEASE' into namespace '$NAMESPACE' from chart '$CHART_DIR'..."
+helm upgrade --install "$RELEASE" "$CHART_DIR" \
+  --namespace "$NAMESPACE" --create-namespace \
+  --wait --timeout 10m
+
+echo "Done. To view resources: kubectl get all -n $NAMESPACE"

+ 10 - 0
rabbitmq-chart/mqtt-tests/go.mod

@@ -0,0 +1,10 @@
+module test-mqtt
+
+go 1.25.3
+
+require (
+	github.com/eclipse/paho.mqtt.golang v1.5.1 // indirect
+	github.com/gorilla/websocket v1.5.3 // indirect
+	golang.org/x/net v0.44.0 // indirect
+	golang.org/x/sync v0.17.0 // indirect
+)

+ 8 - 0
rabbitmq-chart/mqtt-tests/go.sum

@@ -0,0 +1,8 @@
+github.com/eclipse/paho.mqtt.golang v1.5.1 h1:/VSOv3oDLlpqR2Epjn1Q7b2bSTplJIeV2ISgCl2W7nE=
+github.com/eclipse/paho.mqtt.golang v1.5.1/go.mod h1:1/yJCneuyOoCOzKSsOTUc0AJfpsItBGWvYpBLimhArU=
+github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
+github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
+golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I=
+golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY=
+golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug=
+golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=

+ 64 - 0
rabbitmq-chart/mqtt-tests/mqtt.go

@@ -0,0 +1,64 @@
+package main
+
+import (
+	"fmt"
+	"os"
+	"time"
+
+	mqtt "github.com/eclipse/paho.mqtt.golang"
+)
+
+const (
+	//broker   = "tcp://rabbitmq.irdi.eu:1883" // change to your broker's IP/hostname
+	broker   = "tcp://localhost:2222" // change to your broker's IP/hostname
+	topic    = "test/topic"
+	clientID = "go-mqtt-client"
+)
+
+func main() {
+	// Message handler for received messages
+	messagePubHandler := func(client mqtt.Client, msg mqtt.Message) {
+		fmt.Printf("Received message: %s from topic: %s\n", msg.Payload(), msg.Topic())
+	}
+
+	// MQTT connection options
+	opts := mqtt.NewClientOptions()
+	opts.AddBroker(broker)
+	opts.SetClientID(clientID)
+	opts.OnConnect = func(c mqtt.Client) {
+		fmt.Println("Connected to broker")
+	}
+	opts.OnConnectionLost = func(c mqtt.Client, err error) {
+		fmt.Printf("Connection lost: %v\n", err)
+	}
+	opts.SetDefaultPublishHandler(messagePubHandler)
+
+	fmt.Println("Connecting to broker ...")
+
+	// Connect to the broker
+	client := mqtt.NewClient(opts)
+	if token := client.Connect(); token.Wait() && token.Error() != nil {
+		fmt.Printf("Error connecting to broker: %v\n", token.Error())
+		os.Exit(1)
+	}
+
+	// Subscribe to a topic
+	if token := client.Subscribe(topic, 1, nil); token.Wait() && token.Error() != nil {
+		fmt.Printf("Subscribe error: %v\n", token.Error())
+		os.Exit(1)
+	}
+
+	// Publish a message
+	text := "Hello from Go!"
+	token := client.Publish(topic, 0, false, text)
+	token.Wait()
+
+	// Wait to receive message
+	time.Sleep(5 * time.Second)
+
+	// Disconnect
+	client.Disconnect(250)
+	fmt.Println("Disconnected")
+}
+
+// go run mqtt.go

BIN
rabbitmq-chart/mqtt-tests/test-mqtt


+ 81 - 0
rabbitmq-chart/mqtt_test.py

@@ -0,0 +1,81 @@
+import argparse
+import sys
+import paho.mqtt.client as mqtt
+def publish_mqtt(host, port, username, password, topic, message, qos):
+    client = mqtt.Client(client_id="mqtt-test-client", protocol=mqtt.MQTTv311)
+    if username:
+        client.username_pw_set(username, password)
+    try:
+        client.connect(host, port, 60)
+    except Exception as e:
+        print(f"MQTT connect error: {e}")
+        return False
+    info = client.publish(topic, payload=message, qos=qos)
+    info.wait_for_publish()
+    client.disconnect()
+    return info.is_published()
+
+def publish_amqp(host, port, username, password, exchange, routing_key, message):
+    try:
+        import pika
+    except Exception:
+        print("pika not installed; cannot publish via AMQP")
+        return False
+    creds = pika.PlainCredentials(username, password) if username else None
+    params = pika.ConnectionParameters(host=host, port=port, credentials=creds) if creds else pika.ConnectionParameters(host=host, port=port)
+    try:
+        conn = pika.BlockingConnection(params)
+        ch = conn.channel()
+        props = pika.BasicProperties(delivery_mode=2)
+        ok = ch.basic_publish(exchange=exchange, routing_key=routing_key, body=message, properties=props)
+        conn.close()
+        return ok
+    except Exception as e:
+        print(f"AMQP publish error: {e}")
+        return False
+
+def main():
+    parser = argparse.ArgumentParser(description="Publish a test message to RabbitMQ via MQTT (and optional AMQP)")
+    parser.add_argument("--host", default="192.168.1.243", help="MQTT broker host (default: Traefik LB)")
+    parser.add_argument("--port", type=int, default=1883, help="MQTT broker port (default: 1883)")
+    parser.add_argument("--user", default="user", help="username")
+    parser.add_argument("--password", default="changeme", help="password")
+    parser.add_argument("--topic", default="mqtt/test", help="MQTT topic to publish")
+    parser.add_argument("--message", default="Hello from mqtt_test.py", help="Message payload")
+    parser.add_argument("--qos", type=int, choices=[0,1,2], default=1, help="MQTT QoS (0/1/2)")
+    parser.add_argument("--amqp", action="store_true", help="Also publish via AMQP to exchange 'mqtt.test' (routing_key 'mqtt/test')")
+    parser.add_argument("--amqp-host", default="192.168.1.243", help="AMQP host (default: Traefik LB)")
+    parser.add_argument("--amqp-port", type=int, default=5672, help="AMQP port (default: 5672)")
+    args = parser.parse_args()
+
+    print(f"Publishing MQTT -> {args.host}:{args.port} topic={args.topic} qos={args.qos}")
+    ok = publish_mqtt(args.host, args.port, args.user, args.password, args.topic, args.message, args.qos)
+    if ok:
+        print("MQTT publish succeeded")
+    else:
+        print("MQTT publish failed")
+
+    if args.amqp:
+        print(f"Publishing AMQP -> {args.amqp_host}:{args.amqp_port} exchange=mqtt.test routing_key=mqtt/test")
+        ok2 = publish_amqp(args.amqp_host, args.amqp_port, args.user, args.password, "mqtt.test", "mqtt/test", args.message)
+        if ok2:
+            print("AMQP publish succeeded")
+        else:
+            print("AMQP publish failed")
+
+    sys.exit(0 if ok else 2)
+
+if __name__ == "__main__":
+    main()
+
+import paho.mqtt.client as mqtt
+
+def main():
+    print("starting up")
+    client = mqtt.Client(client_id="my_client_id", protocol=mqtt.MQTTv311)
+    client.connect("153.92.153.32", 1883)
+    client.publish("mqtt/test", payload="Hello", qos=1) # QoS 1 or 2 for persistence
+    print("Message published successfully.")
+
+if __name__ == "__main__":
+    main()

+ 2 - 0
rabbitmq-chart/requirements.txt

@@ -0,0 +1,2 @@
+paho-mqtt>=1.6
+pika>=1.3.0

+ 8 - 0
rabbitmq-chart/templates/NOTES.txt

@@ -0,0 +1,8 @@
+1. Get the application URL by running these commands:
+
+  Management UI: https://{{ .Values.ingress.host }}
+
+2. Login with the credentials in the Kubernetes secret:
+
+  username: {{ .Values.rabbitmq.username }}
+  password: {{ .Values.rabbitmq.password }}

+ 9 - 0
rabbitmq-chart/templates/_helpers.tpl

@@ -0,0 +1,9 @@
+{{- define "rabbitmq.fullname" -}}
+{{- printf "%s-%s" .Release.Name "rabbitmq" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{- define "rabbitmq.labels" -}}
+app.kubernetes.io/name: {{ include "rabbitmq.fullname" . }}
+app.kubernetes.io/instance: {{ .Release.Name }}
+app.kubernetes.io/managed-by: Helm
+{{- end -}}

+ 9 - 0
rabbitmq-chart/templates/configmap-definitions.yaml

@@ -0,0 +1,9 @@
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: {{ include "rabbitmq.fullname" . }}-definitions
+  labels:
+{{ include "rabbitmq.labels" . | nindent 4 }}
+data:
+  definitions.json: |
+{{ toJson .Values.definitions.content | indent 4 }}

+ 9 - 0
rabbitmq-chart/templates/configmap-enabled-plugins.yaml

@@ -0,0 +1,9 @@
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: {{ include "rabbitmq.fullname" . }}-enabled-plugins
+  labels:
+{{ include "rabbitmq.labels" . | nindent 4 }}
+data:
+  enabled_plugins: |
+    [rabbitmq_management, rabbitmq_mqtt].

+ 16 - 0
rabbitmq-chart/templates/configmap-rabbitmq-conf.yaml

@@ -0,0 +1,16 @@
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: {{ include "rabbitmq.fullname" . }}-conf
+  labels:
+{{ include "rabbitmq.labels" . | nindent 4 }}
+data:
+  rabbitmq.conf: |
+    ## MQTT plugin configuration from values
+    mqtt.exchange = {{ .Values.mqtt.exchange }}
+    mqtt.allow_anonymous = {{ .Values.mqtt.allow_anonymous }}
+    mqtt.vhost = {{ .Values.mqtt.vhost }}
+{{- if .Values.definitions.enabled }}
+    # Load definitions (queues/exchanges/bindings) from ConfigMap
+    management.load_definitions = /etc/rabbitmq/definitions.json
+{{- end }}

+ 27 - 0
rabbitmq-chart/templates/ingress.yaml

@@ -0,0 +1,27 @@
+{{- if .Values.ingress.enabled }}
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+  name: {{ include "rabbitmq.fullname" . }}-ingress
+  labels:
+    {{- include "rabbitmq.labels" . | nindent 4 }}
+  annotations:
+    kubernetes.io/ingress.className: {{ .Values.ingress.ingressClassName }}
+    cert-manager.io/cluster-issuer: {{ .Values.ingress.clusterIssuer }}
+spec:
+  tls:
+    - hosts:
+        - {{ .Values.ingress.host }}
+      secretName: {{ .Values.ingress.tlsSecretName }}
+  rules:
+    - host: {{ .Values.ingress.host }}
+      http:
+        paths:
+          - path: /
+            pathType: Prefix
+            backend:
+              service:
+                name: {{ include "rabbitmq.fullname" . }}
+                port:
+                  number: {{ .Values.service.managementPort }}
+{{- end }}

+ 8 - 0
rabbitmq-chart/templates/secret.yaml

@@ -0,0 +1,8 @@
+apiVersion: v1
+kind: Secret
+metadata:
+  name: {{ include "rabbitmq.fullname" . }}-credentials
+type: Opaque
+stringData:
+  username: {{ .Values.rabbitmq.username }}
+  password: {{ .Values.rabbitmq.password }}

+ 49 - 0
rabbitmq-chart/templates/service.yaml

@@ -0,0 +1,49 @@
+apiVersion: v1
+kind: Service
+metadata:
+  name: {{ include "rabbitmq.fullname" . }}-headless
+  labels:
+    {{- include "rabbitmq.labels" . | nindent 4 }}
+{{- if .Values.service.annotations }}
+  annotations:
+{{ toYaml .Values.service.annotations | indent 4 }}
+{{- end }}
+spec:
+  clusterIP: None
+  ports:
+    - port: {{ .Values.service.port }}
+      name: amqp
+    - port: 1883
+      name: mqtt
+  selector:
+    app.kubernetes.io/name: {{ include "rabbitmq.fullname" . }}
+
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: {{ include "rabbitmq.fullname" . }}
+  labels:
+    {{- include "rabbitmq.labels" . | nindent 4 }}
+{{- if .Values.service.annotations }}
+  annotations:
+{{ toYaml .Values.service.annotations | indent 4 }}
+{{- end }}
+spec:
+  type: {{ .Values.service.type }}
+  ports:
+    - name: amqp
+      port: {{ .Values.service.port }}
+      targetPort: 5672
+    - name: management
+      port: {{ .Values.service.managementPort }}
+      targetPort: 15672
+    - name: mqtt
+      port: 1883
+      targetPort: 1883
+  {{- if .Values.service.loadBalancerIP }}
+  loadBalancerIP: {{ .Values.service.loadBalancerIP }}
+  {{- end }}
+  externalTrafficPolicy: {{ .Values.service.externalTrafficPolicy }}
+  selector:
+    app.kubernetes.io/name: {{ include "rabbitmq.fullname" . }}

+ 103 - 0
rabbitmq-chart/templates/statefulset.yaml

@@ -0,0 +1,103 @@
+apiVersion: apps/v1
+kind: StatefulSet
+metadata:
+  name: {{ include "rabbitmq.fullname" . }}
+  labels:
+{{ include "rabbitmq.labels" . | indent 4 }}
+spec:
+  serviceName: {{ include "rabbitmq.fullname" . }}-headless
+  replicas: {{ .Values.replicaCount }}
+  selector:
+    matchLabels:
+      app.kubernetes.io/name: {{ include "rabbitmq.fullname" . }}
+  template:
+    metadata:
+      labels:
+{{ include "rabbitmq.labels" . | nindent 8 }}
+    spec:
+{{- if .Values.nodeSelector }}
+      nodeSelector:
+{{ toYaml .Values.nodeSelector | indent 8 }}
+{{- end }}
+{{- if .Values.tolerations }}
+      tolerations:
+{{ toYaml .Values.tolerations | indent 8 }}
+{{- end }}
+      containers:
+        - name: rabbitmq
+          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
+          imagePullPolicy: {{ .Values.image.pullPolicy }}
+          ports:
+            - containerPort: 5672
+              name: amqp
+            - containerPort: 15672
+              name: management
+            - containerPort: 1883
+              name: mqtt
+          env:
+            - name: RABBITMQ_DEFAULT_USER
+              valueFrom:
+                secretKeyRef:
+                  name: {{ include "rabbitmq.fullname" . }}-credentials
+                  key: username
+            - name: RABBITMQ_DEFAULT_PASS
+              valueFrom:
+                secretKeyRef:
+                  name: {{ include "rabbitmq.fullname" . }}-credentials
+                  key: password
+          readinessProbe:
+            tcpSocket:
+              port: 5672
+            initialDelaySeconds: 10
+            periodSeconds: 10
+          livenessProbe:
+            tcpSocket:
+              port: 5672
+            initialDelaySeconds: 20
+            periodSeconds: 20
+          volumeMounts:
+            - name: rabbitmq-data
+              mountPath: /var/lib/rabbitmq
+            - name: rabbitmq-plugins
+              mountPath: /etc/rabbitmq/enabled_plugins
+              subPath: enabled_plugins
+            - name: rabbitmq-conf
+              mountPath: /etc/rabbitmq/rabbitmq.conf
+              subPath: rabbitmq.conf
+            {{- if .Values.definitions.enabled }}
+            - name: rabbitmq-definitions
+              mountPath: /etc/rabbitmq/definitions.json
+              subPath: definitions.json
+            {{- end }}
+      volumes:
+        - name: rabbitmq-plugins
+          configMap:
+            name: {{ include "rabbitmq.fullname" . }}-enabled-plugins
+            items:
+              - key: enabled_plugins
+                path: enabled_plugins
+        - name: rabbitmq-conf
+          configMap:
+            name: {{ include "rabbitmq.fullname" . }}-conf
+            items:
+              - key: rabbitmq.conf
+                path: rabbitmq.conf
+        {{- if .Values.definitions.enabled }}
+        - name: rabbitmq-definitions
+          configMap:
+            name: {{ include "rabbitmq.fullname" . }}-definitions
+            items:
+              - key: definitions.json
+                path: definitions.json
+        {{- end }}
+  volumeClaimTemplates:
+    - metadata:
+        name: rabbitmq-data
+      spec:
+        accessModes: [ "ReadWriteOnce" ]
+{{- if .Values.persistence.storageClass }}
+        storageClassName: {{ .Values.persistence.storageClass }}
+{{- end }}
+        resources:
+          requests:
+            storage: {{ .Values.persistence.size }}

+ 121 - 0
rabbitmq-chart/test_mqtt.py

@@ -0,0 +1,121 @@
+#!/usr/bin/env python3
+"""
+Publish a test MQTT message to the RabbitMQ MQTT plugin.
+
+Usage:
+  ./test_mqtt.py --host rabbitmq.irdi.eu --topic test/topic --message hello
+
+The script returns exit code 0 on success, non-zero on failure.
+"""
+import argparse
+import socket
+import time
+import sys
+
+import paho.mqtt.client as mqtt
+import socket
+try:
+    import pika
+except Exception:
+    pika = None
+
+
+def main():
+    p = argparse.ArgumentParser(description="MQTT publish test")
+    p.add_argument("--host", default="rabbitmq.irdi.eu", help="MQTT host")
+    p.add_argument("--port", type=int, default=1883, help="MQTT port")
+    p.add_argument("--topic", default="test/topic", help="Topic to publish to")
+    p.add_argument("--message", default="hello from test", help="Message payload")
+    p.add_argument("--timeout", type=int, default=10, help="Connect timeout seconds")
+    p.add_argument("--username", default=None, help="Username for MQTT (optional)")
+    p.add_argument("--password", default=None, help="Password for MQTT (optional)")
+    p.add_argument("--exchange", default=None, help="AMQP exchange to publish to (optional)")
+    p.add_argument("--routing-key", default=None, help="AMQP routing key (optional)")
+    p.add_argument("--amqp", action="store_true", help="Publish via AMQP instead of MQTT")
+    args = p.parse_args()
+
+    socket.setdefaulttimeout(args.timeout)
+
+    client = mqtt.Client()
+    if args.username:
+        client.username_pw_set(args.username, args.password)
+
+    connected = False
+
+    def on_connect(client, userdata, flags, rc):
+        nonlocal connected
+        connected = (rc == 0)
+        print(f"on_connect rc={rc}, success={connected}")
+
+    def on_publish(client, userdata, mid):
+        print(f"on_publish mid={mid}")
+
+    client.on_connect = on_connect
+    client.on_publish = on_publish
+
+    # If AMQP mode requested, publish via pika to given exchange/routing key
+    if args.amqp or args.exchange:
+        if pika is None:
+            print("pika is not installed; install requirements.txt to enable AMQP mode")
+            return 5
+        amqp_host = args.host
+        amqp_port = args.port if args.port else 5672
+        try:
+            credentials = None
+            if args.username:
+                credentials = pika.PlainCredentials(args.username, args.password or "")
+            params = pika.ConnectionParameters(host=amqp_host, port=amqp_port, credentials=credentials)
+            conn = pika.BlockingConnection(params)
+            ch = conn.channel()
+            exchange = args.exchange or 'amq.topic'
+            routing_key = args.routing_key or args.topic
+            ch.basic_publish(
+                exchange=exchange,
+                routing_key=routing_key,
+                body=args.message,
+                properties=pika.BasicProperties(delivery_mode=2)
+            )
+            conn.close()
+            print(f"AMQP message published to exchange='{exchange}' routing_key='{routing_key}'")
+            return 0
+        except Exception as e:
+            print("AMQP publish failed:", e)
+            return 6
+
+    # MQTT mode (default)
+    try:
+        client.connect(args.host, args.port, keepalive=60)
+    except Exception as e:
+        print("Connection failed:", e)
+        return 2
+
+    client.loop_start()
+
+    # wait for on_connect (with timeout)
+    waited = 0
+    while not connected and waited < args.timeout:
+        time.sleep(0.2)
+        waited += 0.2
+
+    if not connected:
+        print("Failed to connect within timeout")
+        client.loop_stop()
+        return 3
+
+    try:
+        result, mid = client.publish(args.topic, args.message, qos=1)
+        print("publish result:", result, "mid:", mid)
+    except Exception as e:
+        print("Publish failed:", e)
+        client.loop_stop()
+        return 4
+
+    time.sleep(1)
+    client.loop_stop()
+    client.disconnect()
+    print("Message sent")
+    return 0
+
+
+if __name__ == '__main__':
+    sys.exit(main())

+ 88 - 0
rabbitmq-chart/test_send_mqtt_lb.py

@@ -0,0 +1,88 @@
+#!/usr/bin/env python3
+"""Send a single MQTT message to the Traefik LB IP to verify external MQTT connectivity.
+
+Defaults to host 153.92.153.32, port 1883, topic mqtt/test, message "test message", user: user, pass: changeme.
+Exits 0 on success, non-zero on failure.
+"""
+import sys
+import time
+import argparse
+
+import paho.mqtt.client as mqtt
+
+
+def main():
+    p = argparse.ArgumentParser()
+    p.add_argument('--host', default='153.92.153.32')
+    p.add_argument('--port', type=int, default=1883)
+    p.add_argument('--topic', default='mqtt/test')
+    p.add_argument('--message', default='hello from test_send_mqtt_lb')
+    p.add_argument('--username', default='user')
+    p.add_argument('--password', default='changeme')
+    p.add_argument('--timeout', type=int, default=10)
+    args = p.parse_args()
+
+    connected = False
+    published = False
+
+    def on_connect(client, userdata, flags, rc):
+        nonlocal connected
+        connected = (rc == 0)
+        print(f'on_connect rc={rc}, success={connected}')
+
+    def on_publish(client, userdata, mid):
+        nonlocal published
+        published = True
+        print(f'on_publish mid={mid}')
+
+    client = mqtt.Client()
+    client.username_pw_set(args.username, args.password)
+    client.on_connect = on_connect
+    client.on_publish = on_publish
+
+    try:
+        client.connect(args.host, args.port, keepalive=60)
+    except Exception as e:
+        print('connect failed:', e)
+        return 2
+
+    client.loop_start()
+
+    # wait for connection
+    waited = 0
+    while not connected and waited < args.timeout:
+        time.sleep(0.2)
+        waited += 0.2
+
+    if not connected:
+        print('failed to connect within timeout')
+        client.loop_stop()
+        return 3
+
+    try:
+        result, mid = client.publish(args.topic, args.message, qos=1)
+        print('publish result:', result, 'mid:', mid)
+    except Exception as e:
+        print('publish failed:', e)
+        client.loop_stop()
+        return 4
+
+    # wait for on_publish
+    waited = 0
+    while not published and waited < args.timeout:
+        time.sleep(0.2)
+        waited += 0.2
+
+    client.loop_stop()
+    client.disconnect()
+
+    if published:
+        print('message sent')
+        return 0
+    else:
+        print('message not confirmed published')
+        return 5
+
+
+if __name__ == '__main__':
+    sys.exit(main())

+ 15 - 0
rabbitmq-chart/uninstall.sh

@@ -0,0 +1,15 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+RELEASE=${RELEASE:-rabbitmq}
+NAMESPACE=${NAMESPACE:-rabbitmq}
+
+echo "Uninstalling release '$RELEASE' from namespace '$NAMESPACE'..."
+helm uninstall "$RELEASE" --namespace "$NAMESPACE" || true
+
+if [ "${DELETE_PVCS:-false}" = "true" ]; then
+  echo "DELETE_PVCS=true -> deleting PVCs for release '$RELEASE' in namespace '$NAMESPACE'"
+  kubectl delete pvc -l app.kubernetes.io/instance="$RELEASE" -n "$NAMESPACE" || true
+fi
+
+echo "Uninstall complete. (Set DELETE_PVCS=true to also remove PVCs)"

+ 89 - 0
rabbitmq-chart/values.yaml

@@ -0,0 +1,89 @@
+replicaCount: 3
+
+image:
+  repository: rabbitmq
+  tag: 3.9-management
+  pullPolicy: IfNotPresent
+
+resources: {}
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: |
+  podAntiAffinity:
+    requiredDuringSchedulingIgnoredDuringExecution:
+      - labelSelector:
+          matchLabels:
+            app.kubernetes.io/name: rabbitmq-chart
+        topologyKey: "kubernetes.io/hostname"
+
+persistence:
+  enabled: true
+  storageClass: "longhorn"
+  size: 2Gi
+
+service:
+  type: LoadBalancer
+  port: 5672
+  managementPort: 15672
+  # optional: annotations to add to the LoadBalancer service (eg. metallb pool selectors)
+  annotations: {}
+  # optional: request a specific IP from MetalLB pool (leave empty to auto-assign)
+  loadBalancerIP: ""
+  # externalTrafficPolicy: Cluster|Local
+  externalTrafficPolicy: Cluster
+
+ingress:
+  enabled: true
+  host: rabbitmq.irdi.eu
+  tls: true
+  tlsSecretName: rabbitmq-tls
+  clusterIssuer: cluster-issuer-prod
+  ingressClassName: traefik
+
+rabbitmq:
+  username: user
+  password: changeme
+
+mqtt:
+  enabled: true
+  port: 1883
+  # MQTT-specific configuration
+  exchange: mqtt.topic
+  # allow anonymous MQTT connections (optional)
+  allow_anonymous: true
+  # MQTT vhost to publish into
+  vhost: /
+
+definitions:
+  # set to true to create a ConfigMap with definitions.json and mount it into the pod
+  enabled: true
+  # Default definitions content (JSON). You can override in your values file with
+  # a full definitions JSON payload compatible with RabbitMQ management export format.
+  content:
+    vhosts:
+      - name: "/"
+    exchanges:
+      - name: "mqtt.topic"
+        vhost: "/"
+        type: "topic"
+        durable: true
+        auto_delete: false
+        internal: false
+        arguments: {}
+    queues:
+      - name: "mqtt_queue"
+        vhost: "/"
+        durable: true
+        auto_delete: false
+        arguments: {"x-ha-policy": "all"}
+    bindings:
+      - source: "mqtt.topic"
+        vhost: "/"
+        destination: "mqtt_queue"
+        destination_type: "queue"
+        routing_key: "#"
+        arguments: {}
+

+ 6 - 0
registry/Chart.yaml

@@ -0,0 +1,6 @@
+apiVersion: v2
+name: registry
+description: "Docker registry Helm chart"
+type: application
+version: 0.1.0
+appVersion: "2"

+ 5 - 0
registry/README.md

@@ -0,0 +1,5 @@
+Create a docker registry using helm under the namespace "registry"
+It should use Longhorn for data storage (which is already set up on cluster)
+Ingress should be : Traefik ( already set up)
+Cert-Manager is already set up and should be used.
+The docker registry should answer to https (443) externally to host: "registry.asterisk.is"

+ 5 - 0
registry/docker-registry.sh

@@ -0,0 +1,5 @@
+kubectl create secret docker-registry regcred \
+  --docker-server=registry.asterisk.is \
+  [email protected] \
+  --docker-password=SvDP3K^DfhE4BN@Nyb95 \
+  -n default

+ 35 - 0
registry/readme.md

@@ -0,0 +1,35 @@
+Create a docker registry using helm under the namespace "registry"
+It should use Longhorn for data storage (which is already set up on cluster)
+Ingress should be : Traefik ( already set up)
+Cert-Manager is already set up and should be used.
+The docker registry should answer to https (443) externally to host: "registry.asterisk.is"
+docker users should need to login using user:docker pass:dockerpass
+
+
+
+
+# Tagging an existing image for private registry upload
+
+docker login
+docker tag nginx:alpine registry.asterisk.is/nginx:alpine
+docker push registry.asterisk.is/nginx:alpine
+
+
+# How to use images in Kubernetes
+
+First we need to add secret:
+
+kubectl create secret docker-registry regcred \
+  --docker-server=registry.asterisk.is \
+  --docker-username=myuser \
+  --docker-password=mypassword \
+  -n registry
+
+Reference it through the pod
+
+spec:
+  imagePullSecrets:
+    - name: regcred
+  containers:
+    - name: myapp
+      image: registry.example.com/nginx:alpine

+ 7 - 0
registry/templates/_helpers.tpl

@@ -0,0 +1,7 @@
+{{- define "registry.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{- define "registry.fullname" -}}
+{{- printf "%s-%s" (include "registry.name" .) .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}

+ 47 - 0
registry/templates/deployment.yaml

@@ -0,0 +1,47 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: {{ include "registry.fullname" . }}
+  labels:
+    app.kubernetes.io/name: {{ include "registry.name" . }}
+    app.kubernetes.io/instance: {{ .Release.Name }}
+spec:
+  replicas: {{ .Values.replicaCount }}
+  selector:
+    matchLabels:
+      app.kubernetes.io/name: {{ include "registry.name" . }}
+  template:
+    metadata:
+      labels:
+        app.kubernetes.io/name: {{ include "registry.name" . }}
+        app.kubernetes.io/instance: {{ .Release.Name }}
+    spec:
+      containers:
+        - name: registry
+          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
+          imagePullPolicy: {{ .Values.image.pullPolicy }}
+          ports:
+            - containerPort: {{ .Values.service.port }}
+              name: http
+          env:
+            - name: REGISTRY_AUTH
+              value: htpasswd
+            - name: REGISTRY_AUTH_HTPASSWD_PATH
+              value: /auth/htpasswd
+            - name: REGISTRY_AUTH_HTPASSWD_REALM
+              value: Registry Realm
+          volumeMounts:
+            - name: registry-storage
+              mountPath: /var/lib/registry
+            - name: auth
+              mountPath: /auth
+      volumes:
+        - name: registry-storage
+          persistentVolumeClaim:
+            claimName: {{ include "registry.fullname" . }}-pvc
+        - name: auth
+          secret:
+            secretName: {{ include "registry.fullname" . }}-auth
+            items:
+              - key: htpasswd
+                path: htpasswd

+ 26 - 0
registry/templates/ingress.yaml

@@ -0,0 +1,26 @@
+{{- if .Values.ingress.enabled }}
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+  name: {{ include "registry.fullname" . }}-ingress
+  annotations:
+    kubernetes.io/ingress.class: "traefik"
+    cert-manager.io/cluster-issuer: "{{ .Values.ingress.tls.issuerName }}"
+spec:
+  ingressClassName: {{ .Values.ingress.className }}
+  tls:
+    - hosts:
+        - {{ .Values.ingress.host }}
+      secretName: {{ .Values.ingress.tls.secretName }}
+  rules:
+    - host: {{ .Values.ingress.host }}
+      http:
+        paths:
+          - path: /
+            pathType: Prefix
+            backend:
+              service:
+                name: {{ include "registry.fullname" . }}
+                port:
+                  number: {{ .Values.service.port }}
+{{- end }}

+ 11 - 0
registry/templates/pvc.yaml

@@ -0,0 +1,11 @@
+apiVersion: v1
+kind: PersistentVolumeClaim
+metadata:
+  name: {{ include "registry.fullname" . }}-pvc
+spec:
+  accessModes:
+    - ReadWriteOnce
+  resources:
+    requests:
+      storage: {{ .Values.persistence.size }}
+  storageClassName: {{ .Values.persistence.storageClass }}

+ 14 - 0
registry/templates/secret.yaml

@@ -0,0 +1,14 @@
+{{- if .Values.auth.enabled }}
+apiVersion: v1
+kind: Secret
+metadata:
+  name: {{ include "registry.fullname" . }}-auth
+type: Opaque
+stringData:
+  htpasswd: |
+{{- if .Values.auth.htpasswd }}
+{{ .Values.auth.htpasswd | indent 4 }}
+{{- else }}
+{{ (htpasswd .Values.auth.username .Values.auth.password) | indent 4 }}
+{{- end }}
+{{- end }}

+ 15 - 0
registry/templates/service.yaml

@@ -0,0 +1,15 @@
+apiVersion: v1
+kind: Service
+metadata:
+  name: {{ include "registry.fullname" . }}
+  labels:
+    app.kubernetes.io/name: {{ include "registry.name" . }}
+    app.kubernetes.io/instance: {{ .Release.Name }}
+spec:
+  type: {{ .Values.service.type }}
+  ports:
+    - port: {{ .Values.service.port }}
+      targetPort: {{ .Values.service.port }}
+      protocol: TCP
+  selector:
+    app.kubernetes.io/name: {{ include "registry.name" . }}

+ 31 - 0
registry/values.yaml

@@ -0,0 +1,31 @@
+replicaCount: 1
+
+image:
+  repository: registry
+  tag: "2"
+  pullPolicy: IfNotPresent
+
+service:
+  type: ClusterIP
+  port: 5000
+
+persistence:
+  enabled: true
+  storageClass: longhorn
+  size: 5Gi
+
+ingress:
+  enabled: true
+  className: traefik
+  host: registry.asterisk.is
+  tls:
+    enabled: true
+    secretName: registry-tls
+    issuerName: letsencrypt-prod
+
+auth:
+  enabled: true
+  username: docker
+  password: dockerpass
+  # optional: precomputed htpasswd content (string). If empty, template will generate it from username/password
+  htpasswd: ""

+ 11 - 0
traefik/install.sh

@@ -0,0 +1,11 @@
+# repo
+helm repo add traefik https://helm.traefik.io/traefik
+helm repo update
+
+# namespace
+kubectl create namespace traefik
+
+# installation
+helm install traefik traefik/traefik \
+  --namespace traefik \
+  -f values.yaml

+ 40 - 0
traefik/values.yaml

@@ -0,0 +1,40 @@
+# traefik-values.yaml
+replicas: 1
+
+ports:
+  web:
+    port: 80
+    exposedPort: 80
+  websecure:
+    port: 443
+    exposedPort: 443
+
+service:
+  type: LoadBalancer   # Change to NodePort if bare metal
+  annotations: {}
+
+ingressClass:
+  enabled: true
+  isDefaultClass: true
+  name: traefik
+
+additionalArguments:
+  - "--log.level=INFO"
+  - "--api.dashboard=true"
+  - "--entrypoints.web.address=:80"
+  - "--entrypoints.websecure.address=:443"
+  - "--entrypoints.ssh.address=:22"
+  # Disable Traefik native ACME when using cert-manager; cert-manager will
+  # provision TLS secrets instead. Remove or uncomment the ACME args above
+  # if you want Traefik to manage Let's Encrypt itself.
+
+providers:
+  kubernetesCRD: {}
+  kubernetesIngress: {}
+
+persistence:
+  enabled: true
+  path: /data
+  size: 1Gi
+  accessMode: ReadWriteOnce
+  storageClass: "longhorn"  # use Longhorn storage class