<%#
 Copyright 2013-2019 the original author or authors from the JHipster project.

 This file is part of the JHipster project, see https://www.jhipster.tech/
 for more information.

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
-%>
---
apiVersion: <%= KUBERNETES_CORE_API_VERSION  %>
kind: Secret
metadata:
  name: ds-secret-ref
  namespace: <%= kubernetesNamespace %>
data:
  database-admin-user: "YWRtaW4K"
  database-admin-password: "cGFzc3dvcmQK"
---
apiVersion: <%= KUBERNETES_STATEFULSET_API_VERSION %>
kind: StatefulSet
metadata:
  name: <%= app.baseName.toLowerCase() %>-couchbase
  namespace: <%= kubernetesNamespace %>
spec:
  serviceName: <%= app.baseName.toLowerCase() %>-couchbase
  replicas: <%= app.dbPeerCount %>
  selector:
    matchLabels:
      app: <%= app.baseName.toLowerCase() %>-couchbase
  template:
    metadata:
      labels:
        app: <%= app.baseName.toLowerCase() %>-couchbase
     <%_ if (istio) { _%>
      annotations:
        sidecar.istio.io/inject: "false"
     <%_ } _%>
    spec:
      containers:
      - name: <%= app.baseName.toLowerCase() %>-couchbase
        image: <%= DOCKER_COUCHBASE %>
        env:
        - name: APPLICATION_NAME
          value: <%= app.baseName.toLowerCase() %>-couchbase
        - name: BUCKET
          value: <%= app.baseName.toLowerCase() %>
        - name: COUCHBASE_DATABASE
          value: <%= app.baseName.toLowerCase() %>
        - name: COUCHBASE_ADMIN_USER
          valueFrom:
            secretKeyRef:
              name: ds-secret-ref
              key: database-admin-user
        - name: COUCHBASE_ADMIN_PASSWORD
          valueFrom:
            secretKeyRef:
              name: ds-secret-ref
              key: database-admin-password
        - name: CB_POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: DB_PEER_COUNT
          value: "<%= app.dbPeerCount %>"
        ports:
        - containerPort: 8091
          protocol: TCP
        - containerPort: 8092
          protocol: TCP
        - containerPort: 8093
          protocol: TCP
        - containerPort: 11210
          protocol: TCP
        command:
            - "/bin/bash"
            - "-c"
            - |
                set -x
                set -m
                REPLICA_CNT=$(( $DB_PEER_COUNT - 1))
                CB_POD_NAME=$CB_POD_NAME.<%= app.baseName.toLowerCase() %>-couchbase
                CB_BASE_POD_NAME=<%= app.baseName.toLowerCase() %>-couchbase-0.<%= app.baseName.toLowerCase() %>-couchbase
                cluster_node=
                echo "checking if the cluster is already initialized"
                nc -z -w 1 <%= app.baseName.toLowerCase() %>-couchbase-discovery 8091 2>>/dev/null

                if [ $? -eq 0 ]; then
                    cluster_node=$(couchbase-cli server-list -u ${COUCHBASE_ADMIN_USER} -p ${COUCHBASE_ADMIN_PASSWORD} -c <%= app.baseName.toLowerCase() %>-couchbase-discovery | tail -1 | cut -d ' ' -f 2)
                fi

                set -e

                /entrypoint.sh couchbase-server &

                echo "waiting for http://${CB_POD_NAME}:8091/ui/index.html"
                while [ "$(curl -Isw '%{http_code}' -o /dev/null http://${CB_POD_NAME}:8091/ui/index.html#/)" != 200 ]
                do
                    sleep 5
                done

                if [ "$CB_POD_NAME" != "$CB_BASE_POD_NAME" ]; then
                    echo "Adding ${CB_POD_NAME} to the cluster node ${CB_BASE_POD_NAME}:8091"
                    couchbase-cli server-add --cluster=${CB_BASE_POD_NAME}:8091 --user=${COUCHBASE_ADMIN_USER} --password=${COUCHBASE_ADMIN_PASSWORD} --server-add=${CB_POD_NAME}:8091 --server-add-username=${COUCHBASE_ADMIN_USER} --server-add-password=${COUCHBASE_ADMIN_PASSWORD} --services=data,index,query
                elif [ ! -z "$cluster_node" ] && [ "$CB_POD_NAME" == "$CB_BASE_POD_NAME" ]; then
                    echo "Cluster is active; going to join one of the existing cluster ${cluster_node} nodes"
                    couchbase-cli server-add --cluster=${cluster_node} --user=${COUCHBASE_ADMIN_USER} --password=${COUCHBASE_ADMIN_PASSWORD} --server-add=${CB_POD_NAME}:8091 --server-add-username=${COUCHBASE_ADMIN_USER} --server-add-password=${COUCHBASE_ADMIN_PASSWORD}
                else
                    echo "Initializing jhipster-couchbase cluster"
                    echo "Setup index and memory quota"
                    curl -v -X POST -u '${COUCHBASE_ADMIN_USER}:${COUCHBASE_ADMIN_PASSWORD}' http://127.0.0.1:8091/node/controller/rename -d hostname=${CB_POD_NAME}
                    couchbase-cli cluster-init --cluster ${CB_POD_NAME}:8091 --cluster-name=jhipster-couchbase --cluster-username=${COUCHBASE_ADMIN_USER} --cluster-password=${COUCHBASE_ADMIN_PASSWORD} --cluster-ramsize=500 --cluster-index-ramsize=300 --index-storage-setting default --services=data,index,query
                    echo "Setup bucket $BUCKET"
                    couchbase-cli bucket-create -c ${CB_POD_NAME}:8091 -u ${COUCHBASE_ADMIN_USER} -p ${COUCHBASE_ADMIN_PASSWORD} --bucket=$BUCKET --bucket-type=couchbase --bucket-ramsize=300 --bucket-replica=$REPLICA_CNT --enable-index-replica=1
                    echo "Setup bucket $BUCKET admin user"
                    couchbase-cli bucket-create -c ${CB_POD_NAME}:8091 -u ${COUCHBASE_ADMIN_USER} -p ${COUCHBASE_ADMIN_PASSWORD} --rbac-username=$BUCKET --rbac-password=${COUCHBASE_ADMIN_PASSWORD} --rbac-name=$BUCKET --roles=bucket_admin[$BUCKET]
                fi

                couchbase-cli setting-autofailover -c ${CB_POD_NAME}:8091 -u ${COUCHBASE_ADMIN_USER} -p ${COUCHBASE_ADMIN_PASSWORD} --enable-auto-failover 1 --auto-failover-timeout 30

                set +e
                echo "Waiting for configured nodes to join to initiate rebalance"
                while [ "$CB_POD_NAME" == "$CB_BASE_POD_NAME" ]
                do
                    if [ $(couchbase-cli server-list -u ${COUCHBASE_ADMIN_USER} -p ${COUCHBASE_ADMIN_PASSWORD} -c $CB_BASE_POD_NAME:8091 | wc -l) -ge $DB_PEER_COUNT ]; then
                        couchbase-cli rebalance -c ${CB_BASE_POD_NAME}:8091 -u ${COUCHBASE_ADMIN_USER} -p ${COUCHBASE_ADMIN_PASSWORD}
                        test $? -eq 0 && break
                    fi
                    sleep 10
                done

                fg

        readinessProbe:
          timeoutSeconds: 1
          initialDelaySeconds: 15
          httpGet:
            path: /ui/index.html
            port: 8091
            scheme: HTTP
        livenessProbe:
          timeoutSeconds: 1
          initialDelaySeconds: 30
          httpGet:
            path: /ui/index.html
            port: 8091
            scheme: HTTP
        volumeMounts:
        - name: <%= app.baseName.toLowerCase() %>-couchbase-data
          mountPath: /opt/couchbase/var/lib/couchbase/data/
        resources:
        imagePullPolicy: IfNotPresent
      restartPolicy: Always
      terminationGracePeriodSeconds: 30
  volumeClaimTemplates:
  - metadata:
      name: <%= app.baseName.toLowerCase() %>-couchbase-data
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 1Gi
---
apiVersion: <%= KUBERNETES_CORE_API_VERSION  %>
kind: Service
metadata:
  name: <%= app.baseName.toLowerCase() %>-couchbase
  namespace: <%= kubernetesNamespace %>
  labels:
    app: <%= app.baseName.toLowerCase() %>-couchbase
  annotations:
    service.alpha.kubernetes.io/tolerate-unready-endpoints: "true"
spec:
  ports:
    -
      name: couchbase-8091
      protocol: TCP
      port: 8091
      targetPort: 8091
    -
      name: couchbase-8092
      protocol: TCP
      port: 8092
      targetPort: 8092
    -
      name: couchbase-8093
      protocol: TCP
      port: 8093
      targetPort: 8093
    -
      name: couchbase-11210
      protocol: TCP
      port: 11210
      targetPort: 11210
  clusterIP: None
  type: ClusterIP
  selector:
    app: <%= app.baseName.toLowerCase() %>-couchbase
---
apiVersion: <%= KUBERNETES_CORE_API_VERSION  %>
kind: Service
metadata:
  name: <%= app.baseName.toLowerCase() %>-couchbase-discovery
  namespace: <%= kubernetesNamespace %>
  labels:
    app: <%= app.baseName.toLowerCase() %>-couchbase
spec:
  ports:
    -
      name: couchbase-8091
      protocol: TCP
      port: 8091
      targetPort: 8091
  type: NodePort
  selector:
    app: <%= app.baseName.toLowerCase() %>-couchbase
