# Copyright 2021 Google LLC
#
# 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
#
#     https://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.

timeout: "3600s" # 1 hour
tags:
  - "secure-cicd-cd"
substitutions:
options:
  pool:
    name: $_CLOUDBUILD_PRIVATE_POOL
  substitution_option: 'ALLOW_LOOSE'
  # machineType: 'E2_HIGHCPU_32'
artifacts:
  objects:
    location: gs://$_CACHE_BUCKET_NAME/artifacts/$BRANCH_NAME
    paths:
      - '/workspace/svcs-endpoints-filtered.json'
      - '/workspace/zap_report_${_TARGET_ID}_${_RELEASE_ID}.html'
logsBucket: gs://$_CACHE_BUCKET_NAME/build_logs
steps:

############################### Post-Deploy Checks ###########################

# Get endpoint IPs
- name: $_DEFAULT_REGION-docker.pkg.dev/$PROJECT_ID/$_GAR_REPOSITORY/skaffold-builder
  id: "get-svc-endpoints"
  entrypoint: "/bin/bash"
  args:
    - '-xe'
    - -c
    - |
      gcloud config set project $_CLUSTER_PROJECT
      echo "Target Type ${_TARGET_TYPE}"
      case ${_TARGET_TYPE} in
        "anthos_cluster")
          gcloud container fleet memberships get-credentials $_ANTHOS_MEMBERSHIP
          ;;
        *)
          gcloud container clusters get-credentials $_CLUSTER_NAME --region=$_DEFAULT_REGION
          ;;
      esac

      kubectl get svc -ojson > /workspace/svcs.json

      ### Below only grabs external IP'd svcs
      jq '[.items[] | (select(.status.loadBalancer.ingress != null) | {svc: .metadata.name, endpoint: "\(.status.loadBalancer.ingress[].ip):\(.spec.ports[].port)"})]' /workspace/svcs.json > /workspace/svcs-endpoints-filtered.json

      SVC_NAMES=( $$(jq -r '.[].svc' /workspace/svcs-endpoints-filtered.json))
      ENDPOINTS=( $$(jq -r '.[].endpoint' /workspace/svcs-endpoints-filtered.json))
      echo $$SVC_NAMES > /workspace/svc_names_env.txt
      echo $$ENDPOINTS > /workspace/endpoints_env.txt
  volumes:
    - name: 'zapvolume'
      path: '/zap/wrk'

# ZAProxy Scan
- name: 'gcr.io/cloud-builders/docker'
  id: "zaproxy-endpoint-scan"
  entrypoint: "bash"
  args:
    - -c
    - |
      SVC_NAMES=( $$(cat /workspace/svc_names_env.txt))
      ENDPOINTS=( $$(cat /workspace/endpoints_env.txt))

      INDEX=0
      ENDPOINT="$${ENDPOINTS[$$INDEX]}"
      echo "Checking $$ENDPOINT"

      docker container run --user root -v zapvolume:/zap/wrk/:rw -t owasp/zap2docker-stable zap-baseline.py -t http://$$ENDPOINT -r zap_report_${_TARGET_ID}_${_RELEASE_ID}.html -z '-config api.disablekey=true' -I
      cp /zap/wrk/zap_report_${_TARGET_ID}_${_RELEASE_ID}.html /workspace/zap_report_${_TARGET_ID}_${_RELEASE_ID}.html
  volumes:
    - name: 'zapvolume'
      path: '/zap/wrk'
  waitFor:
    - 'get-svc-endpoints'

# Binary Authorization
- name: $_DEFAULT_REGION-docker.pkg.dev/$PROJECT_ID/$_GAR_REPOSITORY/skaffold-builder
  id: "binary-authorization-checkpoint"
  entrypoint: "/bin/bash"
  args:
    - '-xe'
    - -c
    - |
      # Only run this step if there is an attestor supplied in the trigger substitutions
      # This step will be skipped for the final environment, when there are no more attestations to add
      if [ -n "${_ATTESTOR_NAME}" ]; then
        gcloud config set project ${PROJECT_ID}

        gsutil cp gs://$_CACHE_BUCKET_NAME/artifacts/build-artifacts-notag.json /artifacts/build-artifacts-notag.json
        IMAGES=( $$(jq -r '.builds[].tag' /artifacts/build-artifacts-notag.json))

        # Public Key for attestor
        PUBLIC_KEY_ID=$(gcloud container binauthz attestors describe ${_ATTESTOR_NAME} \
          --format='value(userOwnedGrafeasNote.publicKeys[0].id)')

        for IMAGE in "$${IMAGES[@]}"; do
          HAS_ATTESTATION=$(gcloud container binauthz attestations list \
              --project="${PROJECT_ID}" \
              --attestor="${_ATTESTOR_NAME}" \
              --artifact-url="$${IMAGE}" \
              --format="value(name)")

          if [ -z $${HAS_ATTESTATION} ]; then
            gcloud beta container binauthz attestations sign-and-create \
              --artifact-url="$${IMAGE}" \
              --attestor="${_ATTESTOR_NAME}" \
              --keyversion=$( echo "$${PUBLIC_KEY_ID}" | sed "s|//cloudkms.googleapis.com/v1/||" )

          fi
        done
      else
        echo "_ATTESTOR_NAME not specified. No attestation to add."
      fi
  waitFor:
    - 'zaproxy-endpoint-scan'

############################### Artifact Promotion ###########################

- name: $_DEFAULT_REGION-docker.pkg.dev/$PROJECT_ID/$_GAR_REPOSITORY/skaffold-builder
  id: "promote-manifests"
  entrypoint: "/bin/bash"
  args:
    - '-xe'
    - -c
    - |
      gcloud deploy releases promote --release=$_RELEASE_ID --delivery-pipeline=$_CLOUDDEPLOY_PIPELINE_NAME --region=$_DEFAULT_REGION

  waitFor:
    - 'binary-authorization-checkpoint'
