---
name: enos

on:
  # Only trigger this working using workflow_call. It assumes that secrets are
  # being inherited from the caller.
  workflow_call:
    inputs:
      artifact-build-date:
        required: false
        type: string
      artifact-name:
        required: true
        type: string
      artifact-revision:
        required: true
        type: string
      artifact-source:
        required: false
        type: string
      artifact-version:
        required: true
        type: string

env:
  PKG_NAME: vault
  ARTIFACT_BUILD_DATE: ${{ inputs.artifact-build-date }}
  ARTIFACT_NAME: ${{ inputs.artifact-name }}
  ARTIFACT_REVISION: ${{ inputs.artifact-revision }}
  ARTIFACT_SOURCE: ${{ inputs.artifact-source }}
  ARTIFACT_VERSION: ${{ inputs.artifact-version }}

jobs:
  # Read Enos scenario matrix file based on artifact-name input to test
  read-enos-matrix:
    runs-on: ubuntu-latest
    outputs:
      enos-scenarios: ${{ steps.enos-matrix.outputs.matrix }}
    steps:
      - name: Checkout
        uses: actions/checkout@v3
      - name: Create Enos scenario matrix
        id: enos-matrix
        run: |
          [[ ${{ env.ARTIFACT_NAME }} == *"ent"* ]] && scenarioFile=$(cat ./.github/enos-run-matrices/${{ env.ARTIFACT_SOURCE }}-ent.json |jq -c .) || scenarioFile=$(cat ./.github/enos-run-matrices/${{ env.ARTIFACT_SOURCE }}-oss.json |jq -c .)
          echo "matrix=$scenarioFile" >> $GITHUB_OUTPUT
  # Run Integration tests on Enos scenario matrix
  enos:
    name: Integration
    needs: read-enos-matrix
    strategy:
      fail-fast: false # don't fail as that can skip required cleanup steps for jobs
      matrix: ${{ fromJson(needs.read-enos-matrix.outputs.enos-scenarios) }}
    runs-on: ubuntu-latest
    env:
      GITHUB_TOKEN: ${{ secrets.ELEVATED_GITHUB_TOKEN }}
    steps:
      - name: Checkout
        uses: actions/checkout@v3
      - name: Set up Terraform
        uses: hashicorp/setup-terraform@v2
        with:
          # the Terraform wrapper will break Terraform execution in Enos because
          # it changes the output to text when we expect it to be JSON.
          terraform_wrapper: false
      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: ${{ matrix.aws_region }}
          role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
          role-skip-session-tagging: true
          role-duration-seconds: 3600
      - name: Set up Enos
        uses: hashicorp/action-setup-enos@v1
        with:
          github-token: ${{ secrets.ELEVATED_GITHUB_TOKEN }}
      - name: Set up AWS SSH private key
        run: |
          mkdir -p ./enos/support
          echo "${{ secrets.ENOS_CI_SSH_KEY }}" > ./enos/support/private_key.pem
          chmod 600 ./enos/support/private_key.pem
      - name: Download Linux AMD64 Vault bundle
        if: ${{ env.ARTIFACT_SOURCE == 'crt' }}
        id: download
        uses: actions/download-artifact@v3
        with:
          name: ${{ inputs.artifact-name }}
          path: ./enos/support/downloads
      - name: unzip Downloaded Vault bundle
        if: ${{ env.ARTIFACT_SOURCE == 'crt' }}
        run: |
          unzip ${{steps.download.outputs.download-path}}/*.zip -d enos/support
          mv ${{steps.download.outputs.download-path}}/*.zip enos/support/vault.zip
      - name: Prepare for scenario execution
        run: |
          mkdir -p enos/support/terraform-plugin-cache
          [[ ${{ env.ARTIFACT_NAME }} == *"ent"* ]] && echo "${{ secrets.VAULT_LICENSE }}" > ./enos/support/vault.hclic || true
      - name: Run Enos scenario
        id: run
        # Continue once and retry to handle occasional blips when creating
        # infrastructure.
        continue-on-error: true
        env:
          ENOS_VAR_aws_region: ${{ matrix.aws_region }}
          ENOS_VAR_aws_ssh_keypair_name: enos-ci-ssh-key
          ENOS_VAR_aws_ssh_private_key_path: ./support/private_key.pem
          ENOS_VAR_tfc_api_token: ${{ secrets.TF_API_TOKEN }}
          ENOS_VAR_terraform_plugin_cache_dir: ./support/terraform-plugin-cache
          ENOS_VAR_vault_build_date: ${{ env.ARTIFACT_BUILD_DATE }}
          ENOS_VAR_vault_product_version: ${{ env.ARTIFACT_VERSION }}
          ENOS_VAR_vault_revision: ${{ env.ARTIFACT_REVISION }}
          ENOS_VAR_vault_bundle_path: ./support/vault.zip
        run: |
          enos scenario run --timeout 60m0s --chdir ./enos ${{ matrix.scenario }}
      - name: Retry Enos scenario
        id: run_retry
        if: steps.run.outcome == 'failure'
        env:
          ENOS_VAR_aws_region: ${{ matrix.aws_region }}
          ENOS_VAR_aws_ssh_keypair_name: enos-ci-ssh-key
          ENOS_VAR_aws_ssh_private_key_path: ./support/private_key.pem
          ENOS_VAR_tfc_api_token: ${{ secrets.TF_API_TOKEN }}
          ENOS_VAR_terraform_plugin_cache_dir: ./support/terraform-plugin-cache
          ENOS_VAR_vault_build_date: ${{ env.ARTIFACT_BUILD_DATE }}
          ENOS_VAR_vault_product_version: ${{ env.ARTIFACT_VERSION }}
          ENOS_VAR_vault_revision: ${{ env.ARTIFACT_REVISION }}
          ENOS_VAR_vault_bundle_path: ./support/vault.zip
        run: |
          enos scenario run --timeout 60m0s --chdir ./enos ${{ matrix.scenario }}
      - name: Destroy Enos scenario
        if: ${{ always() }}
        # With Enos version 0.0.11 the destroy step returns an error if the infrastructure
        # is already destroyed by enos run. So temporarily setting it to continue on error in GHA
        continue-on-error: true
        env:
          ENOS_VAR_aws_region: ${{ matrix.aws_region }}
          ENOS_VAR_aws_ssh_keypair_name: enos-ci-ssh-key
          ENOS_VAR_aws_ssh_private_key_path: ./support/private_key.pem
          ENOS_VAR_tfc_api_token: ${{ secrets.TF_API_TOKEN }}
          ENOS_VAR_terraform_plugin_cache_dir: ./support/terraform-plugin-cache
          ENOS_VAR_vault_build_date: ${{ env.ARTIFACT_BUILD_DATE }}
          ENOS_VAR_vault_product_version: ${{ env.ARTIFACT_VERSION }}
          ENOS_VAR_vault_revision: ${{ env.ARTIFACT_REVISION }}
          ENOS_VAR_vault_bundle_path: ./support/vault.zip
        run: |
          enos scenario destroy --timeout 60m0s --chdir ./enos ${{ matrix.scenario }}
      - name: Cleanup Enos runtime directories
        if: ${{ always() }}
        run: |
          rm -rf /tmp/enos*
          rm -rf ./enos/support
          rm -rf ./enos/.enos
