--- # 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