From ecac4a692487170adeeccbfdc5d7a97e195c98f2 Mon Sep 17 00:00:00 2001
From: Marco GILLES <marco.gilles.ext@orange.com>
Date: Fri, 16 Jun 2023 18:16:52 +0000
Subject: [PATCH] feat(gcp): add OIDC authentication support for GCP Artifact
 Registry

---
 README.md                          | 51 ++++++++++++++++++++++++++++++
 kicker.json                        | 42 ++++++++++++++++++++++++
 templates/gitlab-ci-docker-gcp.yml | 16 ++++++++++
 3 files changed, 109 insertions(+)
 create mode 100644 templates/gitlab-ci-docker-gcp.yml

diff --git a/README.md b/README.md
index 96ade75..4fe491e 100644
--- a/README.md
+++ b/README.md
@@ -564,3 +564,54 @@ variables:
     VAULT_BASE_URL: "https://vault.acme.host/v1"
     # $VAULT_ROLE_ID and $VAULT_SECRET_ID defined as a secret CI/CD variable
 ```
+
+### Google Cloud variant
+
+This variant allows publishing your container images to Google Cloud's [Artifact Registry](https://cloud.google.com/artifact-registry).
+
+:warning: this template doesn't support Google Cloud's [Container Registry](https://cloud.google.com/container-registry) that is [deprecated](https://cloud.google.com/container-registry/docs/deprecations/container-registry-deprecation) and whose support will be discontinued in May 2024.
+
+List of requirements before using this variant for publishing your container images:
+
+1. You must have a **Docker** repository in Artifact Registry,
+2. You must have a Workload Identity Federation Pool,
+3. You must have a Service Account with enough permissions to push to your Artifact Registry repository.
+
+#### Configuration
+
+| Name                     | description                            | default value     |
+| ------------------------ | -------------------------------------- | ----------------- |
+| `TBC_GCP_PROVIDER_IMAGE` | The [GCP Auth Provider](https://gitlab.com/to-be-continuous/tools/gcp-auth-provider) image to use (can be overridden) | `$CI_REGISTRY/to-be-continuous/tools/gcp-auth-provider:main` |
+| `GCP_OIDC_PROVIDER`      | Default Workload Identity Provider associated with GitLab to [authenticate with OpenID Connect](https://docs.gitlab.com/ee/ci/cloud_services/google_cloud/) | _none_ |
+| `GCP_OIDC_ACCOUNT`       | Default Service Account to which impersonate with OpenID Connect authentication | _none_ |
+| `GCP_SNAPSHOT_OIDC_PROVIDER` | Workload Identity Provider to push the snapshot image _(only define if different from default)_ | _none_ |
+| `GCP_SNAPSHOT_OIDC_ACCOUNT`  | Service Account to use to push the snapshot image _(only define if different from default)_ | _none_ |
+| `GCP_RELEASE_OIDC_PROVIDER`  | Workload Identity Provider to push the release image _(only define if different from default)_ | _none_ |
+| `GCP_RELEASE_OIDC_ACCOUNT`   | Service Account to use to push the release image _(only define if different from default)_ | _none_ |
+
+#### Example
+
+```yaml
+include:
+  - project: 'to-be-continuous/docker'
+    ref: "feature/gcp_af_login"
+    file: '/templates/gitlab-ci-docker.yml'
+  - project: 'to-be-continuous/docker'
+    ref: "feature/gcp_af_login"
+    file: '/templates/gitlab-ci-docker-gcp.yml'
+
+variables:
+  # untested & unverified container image
+  DOCKER_SNAPSHOT_IMAGE: "{GCP_REGION}-docker.pkg.dev/{GCP_PROJECT_ID}/{YOUR_REPOSITORY}/{YOUR_IMAGE_NAME}/snapshot"
+  # validated container image (published)
+  DOCKER_RELEASE_IMAGE: "{GCP_REGION}-docker.pkg.dev/{GCP_PROJECT_ID}/{YOUR_REPOSITORY}/{YOUR_IMAGE_NAME}"
+  # default WIF provider
+  GCP_OIDC_PROVIDER: "projects/{GCP_PROJECT_NUMBER}/locations/global/workloadIdentityPools/{YOUR_WIF_POOL_NAME}/providers/gitlab-diod"
+  # default GCP Service Account
+  GCP_OIDC_ACCOUNT: "{YOUR_REGISTRY_SA}@{GCP_PROJECT_ID}.iam.gserviceaccount.com"
+  # WIF provider for snapshot images
+  GCP_SNAPSHOT_OIDC_PROVIDER: "projects/{GCP_PROJECT_NUMBER}/locations/global/workloadIdentityPools/{YOUR_WIF_POOL_NAME}/providers/gitlab-diod"
+  # GCP Service Account for snapshot images
+  GCP_SNAPSHOT_OIDC_ACCOUNT: "{YOUR_REGISTRY_SA}@{GCP_PROJECT_ID}.iam.gserviceaccount.com"
+  DOCKER_BUILD_TOOL: "kaniko" # Only Kaniko has been proved to work for this use case YET
+```
diff --git a/kicker.json b/kicker.json
index 630b66c..ce3b359 100644
--- a/kicker.json
+++ b/kicker.json
@@ -242,6 +242,48 @@
           "secret": true
         }
       ]
+    },
+    {
+      "id": "gcp",
+      "name": "Google Cloud",
+      "description": "Retrieves a registry authentication for the Google Cloud's [Artifact Registry](https://cloud.google.com/artifact-registry)",
+      "template_path": "templates/gitlab-ci-docker-gcp.yml",
+      "variables": [
+        {
+          "name": "TBC_GCP_PROVIDER_IMAGE",
+          "description": "The [GCP Auth Provider](https://gitlab.com/to-be-continuous/tools/gcp-auth-provider) image to use",
+          "default": "$CI_REGISTRY/to-be-continuous/tools/vault-secrets-provider:master",
+          "advanced": true
+        },
+        {
+          "name": "GCP_OIDC_ACCOUNT",
+          "description": "Default Service Account to which impersonate with OpenID Connect authentication"
+        },
+        {
+          "name": "GCP_OIDC_PROVIDER",
+          "description": "Default Workload Identity Provider associated with GitLab to [authenticate with OpenID Connect](https://docs.gitlab.com/ee/ci/cloud_services/google_cloud/)"
+        },
+        {
+          "name": "GCP_SNAPSHOT_OIDC_ACCOUNT",
+          "description": "Service Account to use to push the snapshot image _(only define if different from default)_",
+          "advanced": true
+        },
+        {
+          "name": "GCP_SNAPSHOT_OIDC_PROVIDER",
+          "description": "Workload Identity Provider to push the snapshot image _(only define if different from default)_",
+          "advanced": true
+        },
+        {
+          "name": "GCP_RELEASE_OIDC_ACCOUNT",
+          "description": "Service Account to use to push the release image _(only define if different from default)_",
+          "advanced": true
+        },
+        {
+          "name": "GCP_RELEASE_OIDC_PROVIDER",
+          "description": "Workload Identity Provider to push the release image _(only define if different from default)_",
+          "advanced": true
+        }
+      ]
     }
   ]
 }
diff --git a/templates/gitlab-ci-docker-gcp.yml b/templates/gitlab-ci-docker-gcp.yml
new file mode 100644
index 0000000..3a67bef
--- /dev/null
+++ b/templates/gitlab-ci-docker-gcp.yml
@@ -0,0 +1,16 @@
+# =====================================================================================================================
+# === GCP Auth template variant
+# =====================================================================================================================
+variables:
+    TBC_GCP_AUTH_PROVIDER: "$CI_REGISTRY/to-be-continuous/tools/gcp-auth-provider:main"
+    CI_JOB_JWT_V2: $CI_JOB_JWT_V2 # For the gitlab runner authentication in TBC_GCP_AUTH_PROVIDER
+    DOCKER_REGISTRY_SNAPSHOT_USER: oauth2accesstoken
+    DOCKER_REGISTRY_RELEASE_USER: oauth2accesstoken
+    DOCKER_REGISTRY_SNAPSHOT_PASSWORD: '@url@http://gcp-auth-provider/token?envType=snapshot'
+    DOCKER_REGISTRY_RELEASE_PASSWORD: '@url@http://gcp-auth-provider/token?envType=release'
+.docker-base:
+  services:
+    - name: "$TBC_TRACKING_IMAGE"
+      command: ["--service", "docker", "5.1.0"]
+    - name: "$TBC_GCP_AUTH_PROVIDER"
+      alias: "gcp-auth-provider"
-- 
GitLab