Improve error messaging for CI_JOB_TOKEN on deployment, environment APIs

Original issue: #439655 (closed)

What does this MR do and why?

The goal of this MR is to improve error messaging when CI_JOB_TOKEN is used to access the environment and deployment API.

Instead of presenting abstract error message: {"message":"404 Project not found"}

In case when we get rejected because of CI_JOB_TOKEN permission we will expose the following error: Authentication by CI/CD job token not allowed from %{source_project_path} to %{target_project_path}.

A new error message applies to the following APIs for requests using CI_JOB_TOKEN:

Depoyments API

  1. GET /projects/:id/deployments
  2. GET /projects/:id/deployments/:deployment_id
  3. POST /projects/:id/deployments
  4. PUT /projects/:id/deployments/:deployment_id
  5. DELETE /projects/:id/deployments/:deployment_id
  6. GET /projects/:id/deployments/:deployment_id/merge_requests

Environments API

  1. GET /projects/:id/environments
  2. POST /projects/:id/environments
  3. PUT /projects/:id/environments/:environment_id
  4. DELETE /projects/:id/environments/review_apps
  5. DELETE /projects/:id/environments/:environment_id
  6. POST /projecsts/:id/environments/:environment_id/stop
  7. POST /projects/:id/environments/stop_stale
  8. GET `/projects/:id/environments/:environment_id'

Job artifacts API

  1. GET /projects/:id/jobs/:job_id/artifacts
  2. GET /projects/:id/jobs/artifacts/:ref_name/download?job=name
  3. GET /projects/:id/jobs/:job_id/artifacts/*artifact_path
  4. GET /projects/:id/jobs/artifacts/:ref_name/raw/*artifact_path?job=name
  5. POST /projects/:id/jobs/:job_id/artifacts/keep
  6. DELETE /projects/:id/jobs/:job_id/artifacts
  7. DELETE /projects/:id/artifacts

Packages API

Project Packages

  1. GET /projects/:id/packages
  2. GET /projects/:id/packages/:package_id
  3. GET /projects/:id/packages/:package_id/pipelines
  4. DELETE /projects/:id/packages/:package_id

Pipelines API - Update pipeline metadata

  1. PUT /projects/:id/pipelines/:pipeline_id/metadata

Release links API

  1. GET /projects/:id/releases/:tag_name/assets/links
  2. GET /projects/:id/releases/:tag_name/assets/links/:link_id
  3. PUT /projects/:id/releases/:tag_name/assets/links/:link_id
  4. DELETE /projects/:id/releases/:tag_name/assets/links/:link_id
  5. POST /projects/:id/releases/:tag_name/assets/links

Releases API

  1. GET /projects/:id/releases
  2. GET /projects/:id/releases/:tag_name
  3. GET /projects/:id/releases/:tag_name/downloads/:direct_asset_path
  4. GET /projects/:id/releases/permalink/latest
  5. POST /projects/:id/releases
  6. POST /projects/:id/releases/:tag_name/evidence
  7. PUT /projects/:id/releases/:tag_name
  8. DELETE /projects/:id/releases/:tag_name

MR acceptance checklist

Please evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

Screenshots or screen recordings

Screenshots are required for UI changes, and strongly recommended for all other merge requests.

Before After
Environments API before Environments API after
environments_project_not_found image
Deployments API before Deployments API after
deployments_project_not_found image
Job artifacts API before Job artifacts API after
image image
Package file API before Package file API after
image image
Update pipeline metadata API before Update pipeline metadata API after
image image
Release links API before Release links API after
image image

How to set up and validate locally

Define various of jobs in .gitlab-ci.yml Configure two projects:

  1. git_clone_source_project
  2. test_ci_job_token_git_clone

Create a .gitlab-ci.yml file on test_ci_job_token_git_clone with following instructions on the top

stages:
  - git
  - repo_api
  - deployment_api
  - environment_api
  - job_artifacts_api
  - job_api
  - package_api
  - trigger_api
  - update_pipeline_metadata_api
  - release_links_api

variables:
  SOURCE_PROJECT: "dmitry/test_ci_job_token_errors/git_clone_source_project.git"
  SOURCE_PROJECT_ID: "98"
  CURRENT_PROJECT_ID: "97"
get_list_of_deployments:
  stage: deployment_api
  needs: []
  script:
    - 'curl -vvv --header "JOB-TOKEN: ${CI_JOB_TOKEN}" "http://${CI_SERVER_HOST}:3000/api/v4/projects/${SOURCE_PROJECT_ID}/deployments"'

get_list_of_environments:
  stage: environment_api
  needs: []
  script:
    - 'curl -vvv --header "JOB-TOKEN: ${CI_JOB_TOKEN}" "http://${CI_SERVER_HOST}:3000/api/v4/projects/${SOURCE_PROJECT_ID}/environments"'

download_job_artifact:
  stage: job_artifacts_api
  needs: []
  script:
    - 'curl -vvv --location --output artifacts.zip --header "JOB-TOKEN: ${CI_JOB_TOKEN}" "http://${CI_SERVER_HOST}:3000/api/v4/projects/${SOURCE_PROJECT_ID}/jobs/${SOURCE_JOB_ID}/artifacts"'
    - 'cat artifacts.zip'
 
download_package:
  stage: package_api
  needs: []
  script:
    - 'curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" "${CI_API_V4_URL}/projects/${SOURCE_PROJECT_ID}/packages/26"'

update_pipeline_metadata_api:
  stage: update_pipeline_metadata_api
  needs: []
  script:
    - 'curl --request PUT --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --data "name=Some new pipeline name" "${CI_API_V4_URL}/projects/${SOURCE_PROJECT_ID}/pipelines/8213/metadata"'

create_release_link:
  stage: release_links_api
  needs: []
  script:
    - 'POSTFIX=$(echo $RANDOM)'
    - 'curl --fail-with-body --request POST --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --data name="my-release-amd64-${POSTFIX}" --data url="http://gdk.test:3000/test_link_${POSTFIX}" --data direct_asset_path="/bin/hello-test-${POSTFIX}" "${CI_API_V4_URL}/projects/${SOURCE_PROJECT_ID}/releases/my-release-amd64/assets/links"'

get_links_of_release:
  stage: release_links_api
  needs: []
  script:
    - 'curl --fail-with-body --header "JOB-TOKEN: ${CI_JOB_TOKEN}" "${CI_API_V4_URL}/projects/${SOURCE_PROJECT_ID}/releases/my-release-amd64/assets/links"'

get_releases:
  stage: release_links_api
  needs: []
  script:
    - 'curl --fail-with-body --header "JOB-TOKEN: ${CI_JOB_TOKEN}" "${CI_API_V4_URL}/projects/${SOURCE_PROJECT_ID}/releases"'
Edited by Dmytro Biryukov

Merge request reports

Loading