apiVersion: v1
kind: ConfigMap
metadata:
  name: postgres-2
data:
  pg_hba.conf: |+
    # TYPE  DATABASE        USER            ADDRESS                 METHOD
    host     replication     replicationuser         0.0.0.0/0        md5
    # "local" is for Unix domain socket connections only
    local   all             all                                     trust
    # IPv4 local connections:
    host    all             all             127.0.0.1/32            trust
    # IPv6 local connections:
    host    all             all             ::1/128                 trust
    # Allow replication connections from localhost, by a user with the
    # replication privilege.
    local   replication     all                                     trust
    host    replication     all             127.0.0.1/32            trust
    host    replication     all             ::1/128                 trust

    host all all all scram-sha-256
  postgresql.conf: |+
    data_directory = '/data/pgdata'
    hba_file = '/config/pg_hba.conf'
    ident_file = '/config/pg_ident.conf'

    port = 5432
    listen_addresses = '*'
    max_connections = 100
    shared_buffers = 128MB
    dynamic_shared_memory_type = posix
    max_wal_size = 1GB
    min_wal_size = 80MB
    log_timezone = 'Etc/UTC'
    datestyle = 'iso, mdy'
    timezone = 'Etc/UTC'

    #locale settings
    lc_messages = 'en_US.utf8'			# locale for system error message
    lc_monetary = 'en_US.utf8'			# locale for monetary formatting
    lc_numeric = 'en_US.utf8'			# locale for number formatting
    lc_time = 'en_US.utf8'				# locale for time formatting

    default_text_search_config = 'pg_catalog.english'

    #replication
    wal_level = replica
    archive_mode = on
    archive_command = 'test ! -f /data/archive/%f && cp %p /data/archive/%f'
    max_wal_senders = 3
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: postgres-2
spec:
  selector:
    matchLabels:
      app: postgres-2
  serviceName: "postgres-2"
  replicas: 1
  template:
    metadata:
      labels:
        app: postgres-2
    spec:
      terminationGracePeriodSeconds: 30
      initContainers:
      - name: init
        image: postgres:15.0
        command: [ "bash", "-c" ]
        args:
        - |
          if [ ${STANDBY_MODE} == "on" ]; 
          then
            # initialize from backup if data dir is empty
            if [ -z "$(ls -A ${PGDATA})" ]; then
              export PGPASSWORD=${REPLICATION_PASSWORD}
              pg_basebackup -h ${PRIMARY_SERVER_ADDRESS} -p 5432 -U ${REPLICATION_USER} -D ${PGDATA} -Fp -Xs -R
            fi
          else
            #create archive directory
            mkdir -p /data/archive && chown -R 999:999 /data/archive

            #create a init template
            echo "CREATE USER #REPLICATION_USER REPLICATION LOGIN ENCRYPTED PASSWORD '#REPLICATION_PASSWORD';" > init.sql
            
            # add credential
            sed -i 's/#REPLICATION_USER/'${REPLICATION_USER}'/g' init.sql
            sed -i 's/#REPLICATION_PASSWORD/'${REPLICATION_PASSWORD}'/g' init.sql

            mkdir -p /docker-entrypoint-initdb.d/
            cp init.sql /docker-entrypoint-initdb.d/init.sql
          fi
        env:
        - name: STANDBY_MODE
          value: "on"
        - name: PRIMARY_SERVER_ADDRESS
          value: "postgres-1"
        - name: PGDATA
          value: "/data/pgdata"
        - name: REPLICATION_USER
          valueFrom:
            secretKeyRef:
              name: postgresql
              key: REPLICATION_USER
              optional: false
        - name: REPLICATION_PASSWORD
          valueFrom:
            secretKeyRef:
              name: postgresql
              key: REPLICATION_PASSWORD
              optional: false
        volumeMounts:
        - mountPath: /docker-entrypoint-initdb.d
          name: initdb
        - name: data
          mountPath: /data
          readOnly: false
      containers:
      - name: postgres
        image: postgres:15.0
        args: ["-c", "config_file=/config/postgresql.conf"]
        ports:
        - containerPort: 5432
          name: database
        env:
        - name: PGDATA
          value: "/data/pgdata"
        - name: POSTGRES_USER
          valueFrom:
            secretKeyRef:
              name: postgresql
              key: POSTGRES_USER
              optional: false
        - name: POSTGRES_PASSWORD
          valueFrom:
            secretKeyRef:
              name: postgresql
              key: POSTGRES_PASSWORD
              optional: false
        - name: POSTGRES_DB
          valueFrom:
            secretKeyRef:
              name: postgresql
              key: POSTGRES_DB
              optional: false
        volumeMounts:
        - name: initdb
          mountPath: /docker-entrypoint-initdb.d
        - name: config
          mountPath: /config
          readOnly: false
        - name: data
          mountPath: /data
          readOnly: false
      volumes:
      - name: config
        configMap:
          name: postgres-2
          defaultMode: 0755
      - name: initdb
        emptyDir: {}
  volumeClaimTemplates:
  - metadata:
      name: data
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: "standard"
      resources:
        requests:
          storage: 100Mi
---
apiVersion: v1
kind: Service
metadata:
  name: postgres-2
  labels:
    app: postgres-2
spec:
  ports:
  - port: 5432
    targetPort: 5432
    name: postgres
  clusterIP: None
  selector:
    app: postgres-2