# =====================================================================================================================
# === JIB template variant
# =====================================================================================================================
variables:
  MAVEN_SBOM_IMAGE: "registry.hub.docker.com/anchore/syft:debug"
  MAVEN_SBOM_OPTS: "--catalogers rpm-db-cataloger,alpmdb-cataloger,apkdb-cataloger,dpkgdb-cataloger,portage-cataloger"
  MAVEN_TRIVY_SECURITY_LEVEL_THRESHOLD: "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL"
  MAVEN_TRIVY_IMAGE: "registry.hub.docker.com/aquasec/trivy:latest"
  MAVEN_TRIVY_ARGS: "--ignore-unfixed --vuln-type os"
  MAVEN_JIB_SNAPSHOT_IMAGE: "$CI_REGISTRY_IMAGE/snapshot:$CI_COMMIT_REF_SLUG"
  MAVEN_JIB_RELEASE_IMAGE: "$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_NAME"
  MAVEN_JIB_BUILD_ARGS: "-Djib.to.image=$MAVEN_JIB_SNAPSHOT_IMAGE"
  MAVEN_JIB_PROD_PUBLISH_STRATEGY: "manual"
  MAVEN_SKOPEO_IMAGE: "quay.io/skopeo/stable:latest"

.mvn-jib-scripts: &mvn-jib-scripts |
  # BEGSCRIPT
  set -e
  
  function configure_registries_auth() {
    maven_jib_snapshot_authn_token=$(echo -n "${MAVEN_JIB_REGISTRY_SNAPSHOT_USER:-${MAVEN_JIB_REGISTRY_USER:-$CI_REGISTRY_USER}}:${MAVEN_JIB_REGISTRY_SNAPSHOT_PASSWORD:-${MAVEN_JIB_REGISTRY_PASSWORD:-$CI_REGISTRY_PASSWORD}}" | base64 | tr -d '\n')
    maven_jib_snapshot_registry_host=$(echo "$MAVEN_JIB_SNAPSHOT_IMAGE" | cut -d/ -f1)

    maven_jib_release_authn_token=$(echo -n "${MAVEN_JIB_REGISTRY_RELEASE_USER:-${MAVEN_JIB_REGISTRY_USER:-$CI_REGISTRY_USER}}:${MAVEN_JIB_REGISTRY_RELEASE_PASSWORD:-${MAVEN_JIB_REGISTRY_PASSWORD:-$CI_REGISTRY_PASSWORD}}" | base64 | tr -d '\n')
    maven_jib_release_registry_host=$(echo "$MAVEN_JIB_RELEASE_IMAGE" | cut -d/ -f1)

    maven_jib_snapshot_config_json=$(echo -n "{\"auths\":{\"$maven_jib_snapshot_registry_host\":{\"auth\":\"$maven_jib_snapshot_authn_token\"},\"HttpHeaders\":{\"User-Agent\":\"$USER_AGENT\"}}}")
    maven_jib_release_config_json=$(echo -n "{\"auths\":{\"$maven_jib_release_registry_host\":{\"auth\":\"$maven_jib_release_authn_token\"},\"HttpHeaders\":{\"User-Agent\":\"$USER_AGENT\"}}}")

    BUILDTOOL_HOME=${BUILDTOOL_HOME:-$HOME}
    # Create Docker auth config (supported by Jib)
    mkdir -p "$BUILDTOOL_HOME/.docker"
    echo "${maven_jib_snapshot_config_json}" > $BUILDTOOL_HOME/.docker/config.json
    echo "${maven_jib_release_config_json}" > $BUILDTOOL_HOME/.docker/release-config.json
    
    log_info "Registry authentication configured for \\e[33;1m${maven_jib_snapshot_registry_host}\\e[0m"
  }
  
  configure_registries_auth

  # ENDSCRIPT
  
mvn-build:
  extends: .mvn-base
  script:
    # initialize Docker auth config
    - *mvn-jib-scripts
    # build and push snapshot container
    - >- 
      mvn ${TRACE+-X} $MAVEN_CLI_OPTS $mvn_settings_opt $java_proxy_args verify 
      com.google.cloud.tools:jib-maven-plugin:build 
      $MAVEN_JIB_BUILD_ARGS
    - output_coverage
    # create dotenv file
    - jib_digest=$(cat target/jib-image.digest | cut -f2 -d':' )
    - jib_repository=${MAVEN_JIB_SNAPSHOT_IMAGE%:*}
    - jib_tag=${MAVEN_JIB_SNAPSHOT_IMAGE##*:}
    - |
      {
        echo "jib_image=$MAVEN_JIB_SNAPSHOT_IMAGE"
        echo "jib_image_digest=$jib_repository@$jib_digest"
        echo "jib_repository=$jib_repository"
        echo "jib_tag=$jib_tag"
        echo "jib_digest=$jib_digest"  
      } > jib.env
  artifacts:
    reports:
      dotenv:
        - jib.env
      
mvn-sbom:
  extends: .mvn-base
  stage: package-test
  image:
    name: $MAVEN_SBOM_IMAGE
    entrypoint: [""]
  # force no dependency
  dependencies: []
  script:
    - mkdir -p -m 777 reports
    - /syft packages $MAVEN_JIB_SNAPSHOT_IMAGE $MAVEN_SBOM_OPTS -o cyclonedx-json=reports/mvn-sbom-${jib_digest}.cyclonedx.json
    - chmod a+r reports/mvn-sbom-${jib_digest}.cyclonedx.json
  artifacts:
    name: "SBOM for container from $CI_PROJECT_NAME on $CI_COMMIT_REF_SLUG"
    expire_in: 1 week
    when: always
    paths:
      - "reports/mvn-jib-sbom-*.cyclonedx.json"
    reports:
      cyclonedx: 
        - "reports/mvn-jib-sbom-*.cyclonedx.json"

mvn-trivy:
  extends: .mvn-base
  stage: package-test
  image:
    name: $MAVEN_TRIVY_IMAGE
    entrypoint: [""]
  dependencies: []
  variables:
    TRIVY_CACHE_DIR: ".trivycache/"
  script: |
    # cache cleanup is needed when scanning images with the same tags, it does not remove the database
    trivy image --clear-cache
    export TRIVY_USERNAME=${MAVEN_JIB_REGISTRY_SNAPSHOT_USER:-${MAVEN_JIB_REGISTRY_USER:-$CI_REGISTRY_USER}}
    export TRIVY_PASSWORD=${MAVEN_JIB_REGISTRY_SNAPSHOT_PASSWORD:-${MAVEN_JIB_REGISTRY_PASSWORD:-$CI_REGISTRY_PASSWORD}}
    export basename=$(echo "${MAVEN_JIB_SNAPSHOT_IMAGE}" | sed 's|[/:]|_|g')
    mkdir -p ./reports
    if [[ -z "${MAVEN_TRIVY_ADDR}" ]]; then
      log_warn "\\e[93mYou are using Trivy in standalone mode. To get faster scans, consider setting the MAVEN_TRIVY_ADDR variable to the address of a Trivy server. More info here: https://aquasecurity.github.io/trivy/latest/docs/references/modes/client-server/\\e[0m"
      trivy image --download-db-only
      export trivy_opts="image"
    else
      log_info "You are using Trivy in client/server mode with the following server: ${MAVEN_TRIVY_ADDR}"
      export trivy_opts="image --server ${MAVEN_TRIVY_ADDR}"
    fi
    # Add common trivy arguments
    export trivy_opts="${trivy_opts} --no-progress --severity ${MAVEN_TRIVY_SECURITY_LEVEL_THRESHOLD} ${MAVEN_TRIVY_ARGS}"
    # GitLab format (no fail)
    trivy ${trivy_opts} --format template --exit-code 0 --template "@/contrib/gitlab.tpl" --output reports/docker-trivy-${basename}.gitlab.json $MAVEN_JIB_SNAPSHOT_IMAGE
    # JSON format (no fail)
    if [[ "$DEFECTDOJO_TRIVY_REPORTS" ]]
    then
      trivy ${trivy_opts} --format json --exit-code 0 --output reports/docker-trivy-${basename}.native.json $MAVEN_JIB_SNAPSHOT_IMAGE
    fi
    # console output (fail)
    trivy ${trivy_opts} --format table --exit-code 1 $MAVEN_JIB_SNAPSHOT_IMAGE
  artifacts:
    when: always
    paths:
    - "reports/jib-trivy-*"
    reports:
      container_scanning: "reports/jib-trivy-*.gitlab.json"
  cache:
    paths:
      - .trivycache/
  rules:
    - if: '$MAVEN_TRIVY_DISABLED == "true"'
      when: never
    - !reference [.test-policy, rules]
            
mvn-deploy-release:
  extends: .mvn-base
  image:
    name: "$MAVEN_SKOPEO_IMAGE"
    entrypoint: [""]
  stage: publish
  variables:
    GIT_STRATEGY: none
  script:
    # initialize Docker auth config
    - *mvn-jib-scripts
    - |
      if [[ "${SEMREL_INFO_ON}" && "${MVN_SEMREL_RELEASE_DISABLED}" != "true" ]]
      then
        if [[ -z "${SEMREL_INFO_NEXT_VERSION}" ]]
        then
          log_warn "[semantic-release] no new version to release: skip"
          exit 0
        else
          MAVEN_JIB_RELEASE_IMAGE=$(echo "$MAVEN_JIB_RELEASE_IMAGE" | sed "s/\(:.*\)\{0,1\}$/:$SEMREL_INFO_NEXT_VERSION/")
          log_info "[semantic-release] new Image tag is set: $MAVEN_JIB_RELEASE_IMAGE"
        fi
      fi

      if [[ "$MAVEN_JIB_SNAPSHOT_IMAGE" == "$MAVEN_JIB_RELEASE_IMAGE" ]]
      then
        log_warn "\\e[93mYou should consider distinguishing snapshot and release images as they do not differ. Skipping publish phase as image has already been created by previous job.\\e[0m"
        exit 0
      fi
      BUILDTOOL_HOME=${BUILDTOOL_HOME:-$HOME}
      skopeo copy --src-authfile $BUILDTOOL_HOME/.docker/config.json --dest-authfile $BUILDTOOL_HOME/.docker/release-config.json ${MAVEN_JIB_PUBLISH_ARGS} docker://$MAVEN_JIB_SNAPSHOT_IMAGE docker://$MAVEN_JIB_RELEASE_IMAGE
      log_info "Well done, your image is published and can be downloaded by doing: docker pull $MAVEN_JIB_RELEASE_IMAGE"
    - jib_digest=$(skopeo inspect --authfile $BUILDTOOL_HOME/.docker/release-config.json --format='{{ .Digest }}' "docker://$MAVEN_JIB_RELEASE_IMAGE")
    - jib_repository=${MAVEN_JIB_RELEASE_IMAGE%:*}
    - jib_tag=${MAVEN_JIB_RELEASE_IMAGE##*:}
    - |
      {
        echo "jib_image=$MAVEN_JIB_RELEASE_IMAGE"
        echo "jib_image_digest=$jib_repository@$jib_digest"
        echo "jib_repository=$jib_repository"
        echo "jib_tag=$jib_tag"
        echo "jib_digest=$jib_digest" 
      } > jib.env
  artifacts:
    reports:
      dotenv:
        - jib.env
  rules:
    # exclude if $MAVEN_DEPLOY_ENABLED not set
    - if: '$MAVEN_DEPLOY_ENABLED != "true"'
      when: never
    # on tag: if semrel info not enabled or semrel integration disabled
    - if: '$CI_COMMIT_TAG'
    # exclude non-production branches
    - if: '$CI_COMMIT_REF_NAME !~ $PROD_REF'
      when: never
    # exclude if snapshot is same as release image and semrel info not enabled or semrel integration disabled
    - if: '$MAVEN_JIB_SNAPSHOT_IMAGE == $MAVEN_JIB_RELEASE_IMAGE && ($SEMREL_INFO_ON == null || $SEMREL_INFO_ON == "" || $MVN_SEMREL_RELEASE_DISABLED == "true")'
      when: never
    - if: '$MAVEN_JIB_PROD_PUBLISH_STRATEGY == "manual"'
      when: manual
    - if: '$MAVEN_JIB_PROD_PUBLISH_STRATEGY == "auto"'

# =====================================================================================================================
# === Disable Maven template jobs not required for Docker Jib pipeline
# =====================================================================================================================

# mvn-build supersedes - deploys a snapshot container to the registry
mvn-deploy-snapshot:
  rules:
    - when: never