apiVersion: v1
kind: ServiceAccount
metadata:
  name: mysql
  labels:
    app.kubernetes.io/name: {{ .Release.Name }}
---
apiVersion: v1
kind: Service
metadata:
  name: mysql
  labels:
    app.kubernetes.io/name: {{ .Release.Name }}
spec:
  ports:
    - port: 3306
  selector:
    {{ if .Values.managedstorage.enabled }}
    app: cloudsqlproxy
    {{ else }}
    app: mysql
    {{ end }}
    app.kubernetes.io/name: {{ .Release.Name }}
---
{{ if .Values.managedstorage.enabled }}
apiVersion: apps/v1
kind: Deployment
metadata:
  name: cloudsqlproxy
  labels:
    app: cloudsqlproxy
    app.kubernetes.io/name: {{ .Release.Name }}
spec:
  selector:
    matchLabels:
      app: cloudsqlproxy
      app.kubernetes.io/name: {{ .Release.Name }}
  replicas: 1
  template:
    metadata:
      labels:
        app: cloudsqlproxy
        app.kubernetes.io/name: {{ .Release.Name }}
    spec:
      serviceAccountName: mysql
      containers:
        - image: {{ .Values.images.cloudsqlproxy}}
          name: cloudsqlproxy
          env:
          command: ["/cloud_sql_proxy",
                    "-dir=/cloudsql",
            # Replace with your own CloudSQL instance ID
                    "-instances={{ .Values.managedstorage.cloudsqlInstanceConnectionName }}=tcp:0.0.0.0:3306",
                    # Enables HTTP health checks.
                    "-use_http_health_check",
            # System workload uses GCE default service account or Workload Identity's service account
            #       "-credential_file=/credentials/application_default_credentials.json",
                    "term_timeout=10s"]
          # set term_timeout if require graceful handling of shutdown
          # NOTE: proxy will stop accepting new connections; only wait on existing connections
          lifecycle:
            preStop:
              exec:
                # (optional) add a preStop hook so that termination is delayed
                # this is required if your server still require new connections (e.g., connection pools)
                command: ['sleep', '10']
          # Liveness probe configuration is adviced by Cloud SQL Proxy examples:
          # https://github.com/GoogleCloudPlatform/cloudsql-proxy/tree/main/examples/k8s-health-check
          # For details, see https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/
          livenessProbe:
            httpGet:
              path: /liveness
              port: 8090
            # Number of seconds after the container has started before the first probe is scheduled. Defaults to 0.
            # Not necessary when the startup probe is in use.
            initialDelaySeconds: 0
            # Frequency of the probe.
            periodSeconds: 60
            # Number of seconds after which the probe times out.
            timeoutSeconds: 30
            # Number of times the probe is allowed to fail before the transition
            # from healthy to failure state.
            #
            # If periodSeconds = 60, 5 tries will result in five minutes of
            # checks. The proxy starts to refresh a certificate five minutes
            # before its expiration. If those five minutes lapse without a
            # successful refresh, the liveness probe will fail and the pod will be
            # restarted.
            failureThreshold: 5
          readinessProbe:
            httpGet:
              path: /readiness
              port: 8090
            initialDelaySeconds: 0
            periodSeconds: 10
            timeoutSeconds: 5
            # Number of times the probe must report success to transition from failure to healthy state.
            # Defaults to 1 for readiness probe.
            successThreshold: 1
            failureThreshold: 1
          startupProbe:
            httpGet:
              path: /startup
              port: 8090
            periodSeconds: 1
            timeoutSeconds: 5
            failureThreshold: 20
          ports:
            - name: mysql
              containerPort: 3306
          volumeMounts:
            - mountPath: /cloudsql
              name: cloudsql
      volumes:
        - name: cloudsql
          emptyDir:
---
apiVersion: v1
kind: Secret
metadata:
  name: mysql-credential
  labels:
    app: mysql-credential
    app.kubernetes.io/name: {{ .Release.Name }}
type: Opaque
data:
  username: {{ .Values.managedstorage.dbUsername | b64enc | quote}}
  password: {{ .Values.managedstorage.dbPassword | b64enc | quote}}
{{ else }}
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-pv-claim
  labels:
    app.kubernetes.io/name: {{ .Release.Name }}
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 20Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql
  labels:
    app.kubernetes.io/name: {{ .Release.Name }}
spec:
  selector:
    matchLabels:
      app: mysql
      app.kubernetes.io/name: {{ .Release.Name }}
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: mysql
        app.kubernetes.io/name: {{ .Release.Name }}
    spec:
      serviceAccountName: mysql
      containers:
        - name: mysql
          image: {{ .Values.images.mysql }}
          args:
          # https://dev.mysql.com/doc/refman/5.7/en/server-options.html#option_mysqld_ignore-db-dir
          # Ext4, Btrfs etc. volumes root directories have a lost+found directory that should not be treated as a database.
          # ignore-db-dir option has been deprecated in mysql v5.7.16.
          #
          # If upgrading MySQL to v8.0 fails, try removing /var/lib/mysql/lost+found folder in 
          # mysql-pv-claim (mysql-persistent-storage):
          #
          # kubectl exec -it <mysql-pod-name> -n kubeflow -- bash
          # rm -rf /var/lib/mysql/lost+found
          #
          # More details on upgrading MySQL can be found here:
          # https://dev.mysql.com/doc/refman/8.0/en/upgrade-prerequisites.html
          # https://dev.mysql.com/doc/refman/8.0/en/upgrade-docker-mysql.html
          - --datadir
          - /var/lib/mysql
          # MLMD workloads (metadata-grpc-deployment and metadata-writer) depend on mysql_native_password authentication plugin.
          # mysql_native_password plugin implements native authentication; that is, authentication based on the password 
          # hashing method in use from before the introduction of pluggable authentication in MySQL 8.0.
          #
          # As default_authentication_plugin option is deprecated in MySQL 8.0.27 this needs to be replaced with
          # appropriate authentication_policy in the next upgrade. See more details:
          # https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_default_authentication_plugin
          # https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_authentication_policy
          - --default-authentication-plugin=mysql_native_password
          # Disable binlog as the logs grow fast and eat up all disk spaces eventually. And KFP doesn't currently utilize binlog.
          # https://dev.mysql.com/doc/refman/8.0/en/replication-options-binary-log.html#option_mysqld_log-bin
          - --disable-log-bin
          env:
            - name: MYSQL_ALLOW_EMPTY_PASSWORD
              value: "true"
          ports:
            - containerPort: 3306
              name: mysql
          volumeMounts:
            - mountPath: /var/lib/mysql
              name: mysql-persistent-storage
          resources:
            requests:
              cpu: 100m
              memory: 800Mi
      volumes:
        - name: mysql-persistent-storage
          persistentVolumeClaim:
            claimName: mysql-pv-claim
{{ end }}
