---
# Source: crds/crd.yaml
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: innodbclusters.mysql.oracle.com
spec:
  group: mysql.oracle.com
  versions:
    - name: v2
      served: true
      storage: true
      schema:
        openAPIV3Schema:
          type: object
          required: ["spec"]
          properties:
            metadata:
              type: object
              properties:
                name:
                  type: string
                  maxLength: 40
            spec:
              type: object
              required: ["secretName"]
              properties:
                secretName:
                  type: string
                  description: "Name of a generic type Secret containing root/default account password"
                tlsCASecretName:
                  type: string
                  description: "Name of a generic type Secret containing CA (ca.pem) and optional CRL (crl.pem) for SSL"
                tlsSecretName:
                  type: string
                  description: "Name of a TLS type Secret containing Server certificate and private key for SSL"
                tlsUseSelfSigned:
                  type: boolean
                  default: false
                  description: "Enables use of self-signed TLS certificates, reducing or disabling TLS based security verifications"
                version:
                  type: string
                  pattern: '^\d+\.\d+\.\d+(-.+)?'
                  description: "MySQL Server version"
                edition:
                  type: string
                  pattern: "^(community|enterprise)$"
                  description: "MySQL Server Edition (community or enterprise)"
                imageRepository:
                  type: string
                  description: "Repository from where images must be pulled from; defaults to mysql for community and container-registry.oracle.com/mysql for enterprise"
                imagePullPolicy:
                  type: string
                  description: "Defaults to Always, but set to IfNotPresent in deploy-operator.yaml when deploying Operator"
                imagePullSecrets:
                  type: array
                  items:
                    type: object
                    properties:
                      name:
                        type: string
                serviceAccountName:
                  type: string
                baseServerId:
                  type: integer
                  minimum: 0
                  maximum: 4294967195
                  default: 1000
                  description: "Base value for MySQL server_id for instances in the cluster"
                datadirVolumeClaimTemplate:
                  type: object
                  x-kubernetes-preserve-unknown-fields: true
                  description: "Template for a PersistentVolumeClaim, to be used as datadir"
                mycnf:
                  type: string
                  description: "Custom configuration additions for my.cnf"
                instances:
                  type: integer
                  minimum: 1
                  maximum: 9
                  default: 1
                  description: "Number of MySQL replica instances for the cluster"
                podSpec:
                  type: object
                  x-kubernetes-preserve-unknown-fields: true
                initDB:
                  type: object
                  properties:
                    clone:
                      type: object
                      required: ["donorUrl", "secretKeyRef"]
                      properties:
                        donorUrl:
                          type: string
                          description: "URL of the cluster to clone from"
                        rootUser:
                          type: string
                          default: "root"
                          description: "User name used for cloning"
                        secretKeyRef:
                          type: object
                          required: ["name"]
                          properties:
                            name:
                              type: string
                              description: "Secret name with key 'rootPassword' storing the password for the user specified in rootUser"
                    dump:
                      type: object
                      required: ["storage"]
                      properties:
                        name:
                          type: string
                          description: "Name of the dump. Not used by the operator, but a descriptive hint for the cluster administrator"
                        path:
                          type: string
                          description: "Path to the dump in the PVC. Use when specifying persistentVolumeClaim. Omit for ociObjectStorage."
                        storage:
                          type: object
                          properties:
                            ociObjectStorage:
                              type: object
                              required: ["bucketName", "prefix", "credentials"]
                              properties:
                                bucketName:
                                  type: string
                                  description: "Name of the bucket where the dump is stored"
                                prefix:
                                  type: string
                                  description: "Path in the bucket where the dump files are stored"
                                credentials:
                                  type: string
                                  description: "Secret name with data for accessing the bucket"
                            persistentVolumeClaim:
                              type: object
                              description : "Specification of the PVC to be used. Used 'as is' in the cloning pod."
                              x-kubernetes-preserve-unknown-fields: true
                  x-kubernetes-preserve-unknown-fields: true
                router:
                  type: object
                  description: "MySQL Router specification"
                  properties:
                    instances:
                      type: integer
                      minimum: 0
                      default: 1
                      description: "Number of MySQL Router instances to deploy"
                    tlsSecretName:
                      type: string
                      description: "Name of a TLS type Secret containing MySQL Router certificate and private key used for SSL"
                    version:
                      type: string
                      pattern: '^\d+\.\d+\.\d+(-.+)?'
                      description: "Override MySQL Router version"
                    podSpec:
                      type: object
                      x-kubernetes-preserve-unknown-fields: true
                backupProfiles:
                  type: array
                  description: "Backup profile specifications for the cluster, which can be referenced from backup schedules and one-off backup jobs"
                  items:
                    type: object
                    required: ["name"]
                    properties:
                      name:
                        type: string
                        description: "Embedded backup profile, referenced as backupProfileName elsewhere"
                      dumpInstance:
                        type: object
                        properties:
                          dumpOptions:
                            type: object
                            description: "A dictionary of key-value pairs passed directly to MySQL Shell's DumpInstance()"
                            x-kubernetes-preserve-unknown-fields: true
                          storage:
                            type: object
                            properties:
                              ociObjectStorage:
                                type: object
                                required: ["bucketName", "prefix", "credentials"]
                                properties:
                                  bucketName:
                                    type: string
                                    description: "Bucket name where backup is stored"
                                  prefix:
                                    type: string
                                    description: "Path in bucket where backup is stored"
                                  credentials:
                                    type: string
                                    description: "Secret name with data for accessing the bucket"
                              persistentVolumeClaim:
                                type: object
                                description : "Specification of the PVC to be used. Used 'as is' in pod executing the backup."
                                x-kubernetes-preserve-unknown-fields: true
                      snapshot:
                        type: object
                        properties:
                          storage:
                            type: object
                            properties:
                              ociObjectStorage:
                                type: object
                                required: ["bucketName", "prefix", "credentials"]
                                properties:
                                  bucketName:
                                    type: string
                                    description: "Bucket name where backup is stored"
                                  prefix:
                                    type: string
                                    description: "Path in bucket where backup is stored"
                                  credentials:
                                    type: string
                                    description: "Secret name with data for accessing the bucket"
                              persistentVolumeClaim:
                                type: object
                                description : "Specification of the PVC to be used. Used 'as is' in pod executing the backup."
                                x-kubernetes-preserve-unknown-fields: true
                    x-kubernetes-preserve-unknown-fields: true
                backupSchedules:
                  type: array
                  description: "Schedules for periodically executed backups"
                  items:
                    type: object
                    required: ["name", "schedule"]
                    x-kubernetes-preserve-unknown-fields: true
                    properties:
                      name:
                        type: string
                        description: "Name of the backup schedule"
                      schedule:
                        type: string
                        description: "The schedule of the job, syntax as a cron expression"
                      backupProfileName:
                        type: string
                        description: "Name of the backupProfile to be used"
                      backupProfile:
                        type: object
                        description: "backupProfile specification if backupProfileName is not specified"
                        x-kubernetes-preserve-unknown-fields: true
                      deleteBackupData:
                        type: boolean
                        default: false
                        description: "Whether to delete the backup data in case the MySQLBackup object created by the job is deleted"
                      enabled:
                        type: boolean
                        default: true
                        description: "Whether the schedule is enabled or not"
            status:
              type: object
              x-kubernetes-preserve-unknown-fields: true
      subresources:
        status: {}
      additionalPrinterColumns:
        - name: Status
          type: string
          description: Status of the InnoDB Cluster
          jsonPath: .status.cluster.status
        - name: Online
          type: integer
          description: Number of ONLINE InnoDB Cluster instances
          jsonPath: .status.cluster.onlineInstances
        - name: Instances
          type: integer
          description: Number of InnoDB Cluster instances configured
          jsonPath: .spec.instances
        - name: Routers
          type: integer
          description: Number of Router instances configured for the InnoDB Cluster
          jsonPath: .spec.router.instances
        - name: Age
          type: date
          jsonPath: .metadata.creationTimestamp
  scope: Namespaced
  names:
    kind: InnoDBCluster
    listKind: InnoDBClusterList
    singular: innodbcluster
    plural: innodbclusters
    shortNames:
      - ic
      - ics
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: mysqlbackups.mysql.oracle.com
spec:
  group: mysql.oracle.com
  scope: Namespaced
  names:
    kind: MySQLBackup
    listKind: MySQLBackupList
    singular: mysqlbackup
    plural: mysqlbackups
    shortNames:
      - mbk
  versions:
    - name: v2
      served: true
      storage: true
      schema:
        openAPIV3Schema:
          type: object
          properties:
            spec:
              type: object
              required: ["clusterName"]
              properties:
                clusterName:
                  type: string
                backupProfileName:
                  type: string
                backupProfile:
                  type: object
                  x-kubernetes-preserve-unknown-fields: true
                addTimestampToBackupDirectory:
                  type: boolean
                  default: true
                deleteBackupData:
                  type: boolean
                  default: false
            status:
              type: object
              properties:
                status:
                  type: string
                startTime:
                  type: string
                completionTime:
                  type: string
                elapsedTime:
                  type: string
                output:
                  type: string
                method:
                  type: string
                source:
                  type: string
                bucket:
                  type: string
                ociTenancy:
                  type: string
                spaceAvailable:
                  type: string
                size:
                  type: string
      subresources:
        status: {}
      additionalPrinterColumns:
        - name: Cluster
          type: string
          description: Name of the target cluster
          jsonPath: .spec.clusterName
        - name: Status
          type: string
          description: Status of the Backup
          jsonPath: .status.status
        - name: Output
          type: string
          description: Name of the produced file/directory
          jsonPath: .status.output
        - name: Age
          type: date
          jsonPath: .metadata.creationTimestamp
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: clusterkopfpeerings.zalando.org
spec:
  scope: Cluster
  group: zalando.org
  names:
    kind: ClusterKopfPeering
    plural: clusterkopfpeerings
    singular: clusterkopfpeering
  versions:
    - name: v1
      served: true
      storage: true
      schema:
        openAPIV3Schema:
          type: object
          properties:
            status:
              type: object
              x-kubernetes-preserve-unknown-fields: true
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: kopfpeerings.zalando.org
spec:
  scope: Namespaced
  group: zalando.org
  names:
    kind: KopfPeering
    plural: kopfpeerings
    singular: kopfpeering
  versions:
    - name: v1
      served: true
      storage: true
      schema:
        openAPIV3Schema:
          type: object
          properties:
            status:
              type: object
              x-kubernetes-preserve-unknown-fields: true

---
# Source: mysql-operator/templates/service_account_operator.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: mysql-operator-sa
  namespace: mysql-operator
---
# Source: mysql-operator/templates/cluster_role_operator.yaml
# The main role for the operator
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: mysql-operator
rules:
  - apiGroups: [""]
    resources: ["pods"]
    verbs: ["get", "list", "watch", "patch"]
  - apiGroups: [""]
    resources: ["pods/status"]
    verbs: ["get", "patch", "update", "watch"]
    # Kopf needs patch on secrets or the sidecar will throw
    # The operator needs this verb to be able to pass it to the sidecar
  - apiGroups: [""]
    resources: ["secrets"]
    verbs: ["get", "create", "list", "watch", "patch"]
  - apiGroups: [""]
    resources: ["configmaps"]
    verbs: ["get", "create", "list", "watch", "patch"]
  - apiGroups: [""]
    resources: ["services"]
    verbs: ["get", "create"]
  - apiGroups: [""]
    resources: ["serviceaccounts"]
    verbs: ["get", "create"]
  - apiGroups: [""]
    resources: ["events"]
    verbs: ["create", "patch", "update"]
  - apiGroups: ["rbac.authorization.k8s.io"]
    resources: ["rolebindings"]
    verbs: ["get", "create"]
  - apiGroups: ["policy"]
    resources: ["poddisruptionbudgets"]
    verbs: ["get", "create"]
  - apiGroups: ["batch"]
    resources: ["jobs"]
    verbs: ["create"]
  - apiGroups: ["batch"]
    resources: ["cronjobs"]
    verbs: ["create", "update", "delete"]
  - apiGroups: ["apps"]
    resources: ["deployments", "statefulsets"]
    verbs: ["get", "create", "patch", "watch", "delete"]
  - apiGroups: ["mysql.oracle.com"]
    resources: ["*"]
    verbs: ["*"]
  - apiGroups: ["zalando.org"]
    resources: ["*"]
    verbs: ["get", "patch", "list", "watch"]
  # Kopf: runtime observation of namespaces & CRDs (addition/deletion).
  - apiGroups: [apiextensions.k8s.io]
    resources: [customresourcedefinitions]
    verbs: [list, watch]
  - apiGroups: [""]
    resources: [namespaces]
    verbs: [list, watch]
---
# Source: mysql-operator/templates/cluster_role_sidecar.yaml
# role for the server sidecar
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: mysql-sidecar
rules:
  - apiGroups: [""]
    resources: ["pods"]
    verbs: ["get", "list", "watch", "patch"]
  - apiGroups: [""]
    resources: ["pods/status"]
    verbs: ["get", "patch", "update", "watch"]
  # Kopf needs patch on secrets or the sidecar will throw
  - apiGroups: [""]
    resources: ["secrets"]
    verbs: ["get", "create", "list", "watch", "patch"]
  - apiGroups: [""]
    resources: ["configmaps"]
    verbs: ["get", "create", "list", "watch", "patch"]
  - apiGroups: [""]
    resources: ["services"]
    verbs: ["get", "create"]
  - apiGroups: [""]
    resources: ["serviceaccounts"]
    verbs: ["get", "create"]
  - apiGroups: [""]
    resources: ["events"]
    verbs: ["create", "patch", "update"]
  - apiGroups: ["apps"]
    resources: ["deployments"]
    verbs: ["get", "patch"]
  - apiGroups: ["mysql.oracle.com"]
    resources: ["innodbclusters"]
    verbs: ["get", "watch", "list"]
  - apiGroups: ["mysql.oracle.com"]
    resources: ["mysqlbackups"]
    verbs: ["create", "get", "list", "patch", "update", "watch", "delete"]
  - apiGroups: ["mysql.oracle.com"]
    resources: ["mysqlbackups/status"]
    verbs: ["get", "patch", "update", "watch"]
---
# Source: mysql-operator/templates/cluster_role_binding_operator.yaml
# Give access to the operator
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: mysql-operator-rolebinding
subjects:
  - kind: ServiceAccount
    name: mysql-operator-sa
    namespace: mysql-operator
  # TODO The following entry is for dev purposes only and must be deleted
  #- kind: Group
  #  name: system:serviceaccounts
  #  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: mysql-operator
  apiGroup: rbac.authorization.k8s.io
---
# Source: mysql-operator/templates/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: mysql-operator
  namespace: mysql-operator
  labels:
    name: mysql-operator
spec:
  type: ClusterIP
  ports:
  - port: 9443
    protocol: TCP
  selector:
    name: mysql-operator
---
# Source: mysql-operator/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql-operator
  namespace: mysql-operator
  labels:
    version: "8.0.30-2.0.6"
    app.kubernetes.io/name: mysql-operator
    app.kubernetes.io/instance: mysql-operator
    app.kubernetes.io/version: "8.0.30-2.0.6"
    app.kubernetes.io/component: controller
    app.kubernetes.io/managed-by: helm
    app.kubernetes.io/created-by: helm
spec:
  replicas: 1
  selector:
    matchLabels:
      name: mysql-operator
  template:
    metadata:
      labels:
        name: mysql-operator
    spec:
      containers:
        - name: mysql-operator
          image: mysql/mysql-operator:8.0.30-2.0.6
          imagePullPolicy: IfNotPresent
          args: ["mysqlsh", "--log-level=@INFO", "--pym", "mysqloperator", "operator"]
          env:
          - name: MYSQLSH_USER_CONFIG_HOME
            value: /mysqlsh
          
          
          - name: MYSQL_OPERATOR_IMAGE_PULL_POLICY
            value: IfNotPresent
          
          volumeMounts:
            - name: mysqlsh-home
              mountPath: /mysqlsh
          securityContext:
            allowPrivilegeEscalation: false
            privileged: false
            readOnlyRootFilesystem: true
      volumes:
        - name: mysqlsh-home
          emptyDir: {}
      serviceAccountName: mysql-operator-sa
---
# Source: mysql-operator/templates/cluster_kopf_keepering.yaml
apiVersion: zalando.org/v1
kind: ClusterKopfPeering
metadata:
  name: mysql-operator