name: TPS Tests

on: [push, pull_request]

jobs:
  init:
    name: Initializing workflow
    runs-on: ubuntu-latest
    outputs:
      matrix: ${{ steps.init.outputs.matrix }}
      repo: ${{ steps.init.outputs.repo }}
    steps:
      - name: Clone repository
        uses: actions/checkout@v2

      - name: Initialize workflow
        id: init
        env:
          BASE64_MATRIX: ${{ secrets.BASE64_MATRIX }}
          BASE64_REPO: ${{ secrets.BASE64_REPO }}
        run: |
          tests/bin/init-workflow.sh

  # docs/development/Building_PKI.md
  build:
    name: Building PKI
    needs: init
    runs-on: ubuntu-latest
    strategy:
      matrix: ${{ fromJSON(needs.init.outputs.matrix) }}
    steps:
      - name: Clone repository
        uses: actions/checkout@v2

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v1

      - name: Build runner image
        uses: docker/build-push-action@v2
        with:
          context: .
          build-args: |
            OS_VERSION=${{ matrix.os }}
            COPR_REPO=${{ needs.init.outputs.repo }}
            BUILD_OPTS=--with-pkgs=base,server,ca,kra,tks,tps --with-timestamp --with-commit-id
          tags: pki-runner
          target: pki-runner
          outputs: type=docker,dest=/tmp/pki-runner.tar

      - name: Upload runner image
        uses: actions/upload-artifact@v2
        with:
          name: pki-runner-${{ matrix.os }}
          path: /tmp/pki-runner.tar

  # docs/installation/tps/Installing_TPS.md
  tps-test:
    name: Testing TPS
    needs: [init, build]
    runs-on: ubuntu-latest
    env:
      PKIDIR: /tmp/workdir/pki
    strategy:
      matrix: ${{ fromJSON(needs.init.outputs.matrix) }}
    steps:
      - name: Clone repository
        uses: actions/checkout@v2

      - name: Download runner image
        uses: actions/download-artifact@v2
        with:
          name: pki-runner-${{ matrix.os }}
          path: /tmp

      - name: Load runner image
        run: docker load --input /tmp/pki-runner.tar

      - name: Run container
        run: |
          IMAGE=pki-runner \
          NAME=pki \
          HOSTNAME=pki.example.com \
          tests/bin/runner-init.sh

      - name: Install dependencies
        run: docker exec pki dnf install -y 389-ds-base

      - name: Install DS
        run: docker exec pki ${PKIDIR}/tests/bin/ds-create.sh

      - name: Install CA
        run: docker exec pki pkispawn -f /usr/share/pki/server/examples/installation/ca.cfg -s CA -v

      - name: Install KRA
        run: docker exec pki pkispawn -f /usr/share/pki/server/examples/installation/kra.cfg -s KRA -v

      - name: Install TKS
        run: docker exec pki pkispawn -f /usr/share/pki/server/examples/installation/tks.cfg -s TKS -v

      - name: Install TPS
        run: docker exec pki pkispawn -f /usr/share/pki/server/examples/installation/tps.cfg -s TPS -v

      - name: Run PKI healthcheck
        run: docker exec pki pki-healthcheck --debug

      - name: Verify TPS admin
        run: |
          docker exec pki pki-server cert-export ca_signing --cert-file ca_signing.crt
          docker exec pki pki client-cert-import ca_signing --ca-cert ca_signing.crt
          docker exec pki pki client-cert-import \
              --pkcs12 /root/.dogtag/pki-tomcat/ca_admin_cert.p12 \
              --pkcs12-password-file /root/.dogtag/pki-tomcat/ca/pkcs12_password.conf
          docker exec pki pki -n caadmin tps-user-show tpsadmin

      - name: Set up TPS authentication
        run: |
          #
          # import sample TPS users
          #
          docker exec pki ldapadd -h pki.example.com -p 389 \
              -D "cn=Directory Manager" \
              -w Secret.123 \
              -f /usr/share/pki/tps/auth/ds/create.ldif
          docker exec pki ldapadd -h pki.example.com -p 389 \
              -D "cn=Directory Manager" \
              -w Secret.123 \
              -f /usr/share/pki/tps/auth/ds/example.ldif
          #
          # configure TPS to use the sample TPS users
          #
          docker exec pki pki-server tps-config-set \
              auths.instance.ldap1.ldap.basedn \
              ou=people,dc=example,dc=com
          docker exec pki pki-server tps-undeploy --wait
          docker exec pki pki-server tps-deploy --wait

      - name: Verify TPS client
        run: |
          #
          # add unformatted token with random CUID
          #
          CUID=`hexdump -v -n "10" -e '1/1 "%02x"' /dev/urandom`
          echo "UNFORMATTED" > expected
          docker exec pki bash -c "pki -n caadmin tps-token-add $CUID | sed -n 's/\s*Status:\s\+\(\S\+\)\s*/\1/p' > ${PKIDIR}/actual"
          diff expected actual
          #
          # format the token
          #
          docker exec pki /usr/share/pki/tps/bin/pki-tps-format \
              --user=testuser \
              --password=Secret.123 \
              $CUID
          echo "FORMATTED" > expected
          docker exec pki bash -c "pki -n caadmin tps-token-show $CUID | sed -n 's/\s*Status:\s\+\(\S\+\)\s*/\1/p' > ${PKIDIR}/actual"
          diff expected actual
          #
          # enroll the token
          #
          docker exec pki /usr/share/pki/tps/bin/pki-tps-enroll \
              --user=testuser \
              --password=Secret.123 \
              $CUID
          echo "ACTIVE" > expected
          docker exec pki bash -c "pki -n caadmin tps-token-show $CUID | sed -n 's/\s*Status:\s\+\(\S\+\)\s*/\1/p' > ${PKIDIR}/actual"
          diff expected actual

      - name: Gather artifacts
        if: always()
        run: |
          tests/bin/ds-artifacts-save.sh pki
          tests/bin/pki-artifacts-save.sh pki
        continue-on-error: true

      - name: Remove TPS
        run: docker exec pki pkidestroy -i pki-tomcat -s TPS -v

      - name: Remove TKS
        run: docker exec pki pkidestroy -i pki-tomcat -s TKS -v

      - name: Remove KRA
        run: docker exec pki pkidestroy -i pki-tomcat -s KRA -v

      - name: Remove CA
        run: docker exec pki pkidestroy -i pki-tomcat -s CA -v

      - name: Remove DS
        run: docker exec pki ${PKIDIR}/tests/bin/ds-remove.sh

      - name: Upload artifacts
        if: always()
        uses: actions/upload-artifact@v2
        with:
          name: tps-${{ matrix.os }}
          path: |
            /tmp/artifacts/pki

  # docs/installation/tps/Installing_TPS_Clone.md
  # This test installs DS, CA, KRA, TKS, and TPS in the primary container,
  # then installs DS clone, CA clone, KRA clone, TKS clone, and TPS clone in the secondary container.
  tps-clone-test:
    name: Testing TPS clone
    needs: [init, build]
    runs-on: ubuntu-latest
    env:
      PKIDIR: /tmp/workdir/pki
    strategy:
      matrix: ${{ fromJSON(needs.init.outputs.matrix) }}
    steps:
      - name: Clone repository
        uses: actions/checkout@v2

      - name: Download runner image
        uses: actions/download-artifact@v2
        with:
          name: pki-runner-${{ matrix.os }}
          path: /tmp

      - name: Load runner image
        run: docker load --input /tmp/pki-runner.tar

      - name: Create network
        run: docker network create example

      - name: Run primary container
        run: |
          IMAGE=pki-runner \
          NAME=primary \
          HOSTNAME=primary.example.com \
          tests/bin/runner-init.sh

      - name: Connect primary container to network
        run: docker network connect example primary --alias primary.example.com

      - name: Install dependencies in primary container
        run: docker exec primary dnf install -y 389-ds-base

      - name: Install DS in primary container
        run: docker exec primary ${PKIDIR}/tests/bin/ds-create.sh

      - name: Install CA in primary container
        run: docker exec primary pkispawn -f /usr/share/pki/server/examples/installation/ca.cfg -s CA -v

      - name: Install KRA in primary container
        run: docker exec primary pkispawn -f /usr/share/pki/server/examples/installation/kra.cfg -s KRA -v

      - name: Install TKS in primary container
        run: docker exec primary pkispawn -f /usr/share/pki/server/examples/installation/tks.cfg -s TKS -v

      - name: Install TPS in primary container
        run: docker exec primary pkispawn -f /usr/share/pki/server/examples/installation/tps.cfg -s TPS -v

      - name: Setup secondary container
        run: |
          IMAGE=pki-runner \
          NAME=secondary \
          HOSTNAME=secondary.example.com \
          tests/bin/runner-init.sh

      - name: Connect secondary container to network
        run: docker network connect example secondary --alias secondary.example.com

      - name: Install dependencies in secondary container
        run: docker exec secondary dnf install -y 389-ds-base

      - name: Install DS in secondary container
        run: docker exec secondary ${PKIDIR}/tests/bin/ds-create.sh

      - name: Install CA in secondary container
        run: |
          docker exec primary pki-server cert-export ca_signing --cert-file ${PKIDIR}/ca_signing.crt
          docker exec primary pki-server ca-clone-prepare --pkcs12-file ${PKIDIR}/ca-certs.p12 --pkcs12-password Secret.123
          docker exec secondary cp ${PKIDIR}/ca_signing.crt .
          docker exec secondary cp ${PKIDIR}/ca-certs.p12 .
          docker exec secondary pkispawn -f /usr/share/pki/server/examples/installation/ca-clone.cfg -s CA -v

      - name: Install KRA in secondary container
        run: |
          docker exec primary pki-server kra-clone-prepare --pkcs12-file ${PKIDIR}/kra-certs.p12 --pkcs12-password Secret.123
          docker exec secondary cp ${PKIDIR}/kra-certs.p12 .
          docker exec secondary pkispawn -f /usr/share/pki/server/examples/installation/kra-clone.cfg -s KRA -v

      - name: Install TKS in secondary container
        run: |
          docker exec primary pki-server tks-clone-prepare --pkcs12-file ${PKIDIR}/tks-certs.p12 --pkcs12-password Secret.123
          docker exec secondary cp ${PKIDIR}/tks-certs.p12 .
          docker exec secondary pkispawn -f /usr/share/pki/server/examples/installation/tks-clone.cfg -s TKS -v

      - name: Install TPS in secondary container
        run: |
          docker exec primary pki-server tps-clone-prepare --pkcs12-file ${PKIDIR}/tps-certs.p12 --pkcs12-password Secret.123
          docker exec secondary cp ${PKIDIR}/tps-certs.p12 .
          docker exec secondary pkispawn -f /usr/share/pki/server/examples/installation/tps-clone.cfg -s TPS -v

      - name: Verify admin user
        run: |
          docker exec primary cp /root/.dogtag/pki-tomcat/ca_admin_cert.p12 ${PKIDIR}/ca_admin_cert.p12
          docker exec primary cp /root/.dogtag/pki-tomcat/ca/pkcs12_password.conf ${PKIDIR}/pkcs12_password.conf
          docker exec secondary pki client-cert-import ca_signing --ca-cert ca_signing.crt
          docker exec secondary pki client-cert-import \
              --pkcs12 ${PKIDIR}/ca_admin_cert.p12 \
              --pkcs12-password-file ${PKIDIR}/pkcs12_password.conf
          docker exec secondary pki -n caadmin tps-user-show tpsadmin

      - name: Gather artifacts from primary container
        if: always()
        run: |
          tests/bin/ds-artifacts-save.sh primary
          tests/bin/pki-artifacts-save.sh primary
        continue-on-error: true

      - name: Gather artifacts from secondary container
        if: always()
        run: |
          tests/bin/ds-artifacts-save.sh secondary
          tests/bin/pki-artifacts-save.sh secondary
        continue-on-error: true

      - name: Remove TPS from secondary container
        run: docker exec secondary pkidestroy -i pki-tomcat -s TPS -v

      - name: Remove TKS from secondary container
        run: docker exec secondary pkidestroy -i pki-tomcat -s TKS -v

      - name: Remove KRA from secondary container
        run: docker exec secondary pkidestroy -i pki-tomcat -s KRA -v

      - name: Remove CA from secondary container
        run: docker exec secondary pkidestroy -i pki-tomcat -s CA -v

      - name: Remove DS from secondary container
        run: docker exec secondary ${PKIDIR}/tests/bin/ds-remove.sh

      - name: Disconnect secondary container from network
        run: docker network disconnect example secondary

      - name: Remove TPS from primary container
        run: docker exec primary pkidestroy -i pki-tomcat -s TPS -v

      - name: Remove TKS from primary container
        run: docker exec primary pkidestroy -i pki-tomcat -s TKS -v

      - name: Remove KRA from primary container
        run: docker exec primary pkidestroy -i pki-tomcat -s KRA -v

      - name: Remove CA from primary container
        run: docker exec primary pkidestroy -i pki-tomcat -s CA -v

      - name: Remove DS from primary container
        run: docker exec primary ${PKIDIR}/tests/bin/ds-remove.sh

      - name: Disconnect primary container from network
        run: docker network disconnect example primary

      - name: Remove network
        run: docker network rm example

      - name: Upload artifacts from primary container
        if: always()
        uses: actions/upload-artifact@v2
        with:
          name: tps-clone-primary-${{ matrix.os }}
          path: |
            /tmp/artifacts/primary

      - name: Upload artifacts from secondary container
        if: always()
        uses: actions/upload-artifact@v2
        with:
          name: tps-clone-secondary-${{ matrix.os }}
          path: |
            /tmp/artifacts/secondary
