name: Constellation verify
description: "Verify a Constellation cluster."

inputs:
  osImage:
    description: "The OS image used in the cluster."
    required: true
  cloudProvider:
    description: "The cloud provider used in the cluster."
    required: true
  kubeconfig:
    description: "The kubeconfig file for the cluster."
    required: true
  cosignPassword:
    required: true
    description: "The password for the cosign private key."
  cosignPrivateKey:
    required: true
    description: "The cosign private key."

runs:
  using: "composite"
  steps:
    - name: Expand version path
      id: expand-version
      uses: ./.github/actions/shortname
      with:
        shortname: ${{ inputs.osImage }}

    - name: Constellation fetch measurements
      shell: bash
      run: |
        if [[ ${{ steps.expand-version.outputs.stream }} == "debug" ]]
        then
          constellation config fetch-measurements --insecure
        else
          constellation config fetch-measurements
        fi

    - name: Constellation verify
      shell: bash
      run: constellation verify --cluster-id $(yq -r ".clusterValues.clusterID" constellation-state.yaml)

    - name: Verify all nodes
      shell: bash
      env:
        KUBECONFIG: ${{ inputs.kubeconfig }}
      run: |
        clusterID=$(yq -r ".clusterValues.clusterID" constellation-state.yaml)
        nodes=$(kubectl get nodes -o json | jq -r ".items[].metadata.name")

        for node in $nodes ; do
          verificationPod=$(kubectl get pods --field-selector spec.nodeName=${node} -n kube-system | grep "verification-service" | cut -d' ' -f1)

          mapfile -t verificationPod <<< "$verificationPod"

          if [[ ${#verificationPod[@]} -ne 1 ]]; then
            echo "Expected 1 verification pod for node ${node}, found ${#verificationPodArray[@]}"
            exit 1
          fi

          echo "Verifying pod ${verificationPod} on node ${node}"

          kubectl wait -n kube-system "pod/${verificationPod}" --for=condition=ready --timeout=5m
          kubectl port-forward -n kube-system "pods/${verificationPod}"  9090:9090 &
          forwarderPID=$!
          sleep 5

          # TODO(v2.15): Remove workaround since we don't need to support v2.13 anymore
          if [[ ${{ inputs.cloudProvider }} == "azure" ]] || { [[ ${{ inputs.cloudProvider }} == "aws" ]] && ! constellation version | grep -q "v2.13."; }; then
            echo "Extracting TCB versions for API update"
            constellation verify --cluster-id "${clusterID}" --node-endpoint localhost:9090 -o json > "snp-report-${node}.json"
          else
            constellation verify --cluster-id "${clusterID}" --node-endpoint localhost:9090
          fi

          kill $forwarderPID
        done

    - name: Login to AWS
      if: github.ref_name == 'main' && inputs.cloudProvider == 'azure'
      uses: aws-actions/configure-aws-credentials@010d0da01d0b5a38af31e9c3470dbfdabdecca3a # v4.0.1
      with:
        role-to-assume: arn:aws:iam::795746500882:role/GitHubConstellationImagePipeline
        aws-region: eu-central-1

    - name: Upload extracted TCBs
      if: github.ref_name == 'main' && (inputs.cloudProvider == 'azure' || inputs.cloudProvider == 'aws')
      shell: bash
      env:
        COSIGN_PASSWORD: ${{ inputs.cosignPassword }}
        COSIGN_PRIVATE_KEY: ${{ inputs.cosignPrivateKey }}
      run: |
        if [[ ${{ inputs.cloudProvider }} == "aws" ]] && constellation version | grep -q "v2.13."; then
          echo "Skipping TCB upload for AWS on CLI v2.13"
          exit 0
        fi

        reports=(snp-report-*.json)
        if [ -z ${#reports[@]} ]; then
            exit 1
        fi

        for file in "${reports[@]}"; do
          path=$(realpath "${file}")
          cat "${path}"
          bazel run //internal/api/attestationconfigapi/cli -- upload ${{ inputs.cloudProvider }} snp-report "${path}"
        done
