Commit 92cb6d63 authored by Grzegorz Bizon's avatar Grzegorz Bizon

Merge branch '44447-expose-deploy-token-to-ci-cd' into 'master'

Expose Deploy Token info as environment variables to CI/CD jobs

Closes #44447

See merge request gitlab-org/gitlab-ce!18414
parents 8a726a08 82d66ac9
......@@ -27,6 +27,7 @@ module Ci
has_one :metadata, class_name: 'Ci::BuildMetadata'
delegate :timeout, to: :metadata, prefix: true, allow_nil: true
delegate :gitlab_deploy_token, to: :project
##
# The "environment" field for builds is a String, and is the unexpanded name!
......@@ -604,6 +605,7 @@ module Ci
.append(key: 'CI_REGISTRY_USER', value: CI_REGISTRY_USER)
.append(key: 'CI_REGISTRY_PASSWORD', value: token, public: false)
.append(key: 'CI_REPOSITORY_URL', value: repo_url, public: false)
.concat(deploy_token_variables)
end
end
......@@ -654,6 +656,15 @@ module Ci
end
end
def deploy_token_variables
Gitlab::Ci::Variables::Collection.new.tap do |variables|
break variables unless gitlab_deploy_token
variables.append(key: 'CI_DEPLOY_USER', value: gitlab_deploy_token.name)
variables.append(key: 'CI_DEPLOY_PASSWORD', value: gitlab_deploy_token.token, public: false)
end
end
def environment_url
options&.dig(:environment, :url) || persisted_environment&.external_url
end
......
......@@ -4,6 +4,7 @@ class DeployToken < ActiveRecord::Base
add_authentication_token_field :token
AVAILABLE_SCOPES = %i(read_repository read_registry).freeze
GITLAB_DEPLOY_TOKEN_NAME = 'gitlab-deploy-token'.freeze
default_value_for(:expires_at) { Forever.date }
......@@ -17,6 +18,10 @@ class DeployToken < ActiveRecord::Base
scope :active, -> { where("revoked = false AND expires_at >= NOW()") }
def self.gitlab_deploy_token
active.find_by(name: GITLAB_DEPLOY_TOKEN_NAME)
end
def revoke!
update!(revoked: true)
end
......
......@@ -1879,6 +1879,10 @@ class Project < ActiveRecord::Base
[]
end
def gitlab_deploy_token
@gitlab_deploy_token ||= deploy_tokens.gitlab_deploy_token
end
private
def storage
......
---
title: Expose Deploy Token data as environment varialbes on CI/CD jobs
merge_request: 18414
author:
type: added
......@@ -260,6 +260,8 @@ are unsupported in environment name context:
- `CI_REGISTRY_PASSWORD`
- `CI_REPOSITORY_URL`
- `CI_ENVIRONMENT_URL`
- `CI_DEPLOY_USER`
- `CI_DEPLOY_PASSWORD`
GitLab Runner exposes various [environment variables][variables] when a job runs,
and as such, you can use them as environment names. Let's add another job in
......
......@@ -87,6 +87,8 @@ future GitLab releases.**
| **GITLAB_USER_LOGIN** | 10.0 | all | The login username of the user who started the job |
| **GITLAB_USER_NAME** | 10.0 | all | The real name of the user who started the job |
| **RESTORE_CACHE_ATTEMPTS** | 8.15 | 1.9 | Number of attempts to restore the cache running a job |
| **CI_DEPLOY_USER** | 10.8 | all | Authentication username of the [GitLab Deploy Token][gitlab-deploy-token], only present if the Project has one related.|
| **CI_DEPLOY_PASSWORD** | 10.8 | all | Authentication password of the [GitLab Deploy Token][gitlab-deploy-token], only present if the Project has one related.|
## 9.0 Renaming
......@@ -546,6 +548,8 @@ You can find a full list of unsupported variables below:
- `CI_REGISTRY_PASSWORD`
- `CI_REPOSITORY_URL`
- `CI_ENVIRONMENT_URL`
- `CI_DEPLOY_USER`
- `CI_DEPLOY_PASSWORD`
These variables are also not supported in a contex of a
[dynamic environment name][dynamic-environments].
......@@ -562,3 +566,4 @@ These variables are also not supported in a contex of a
[subgroups]: ../../user/group/subgroups/index.md
[builds-policies]: ../yaml/README.md#only-and-except-complex
[dynamic-environments]: ../environments.md#dynamic-environments
[gitlab-deploy-token]: ../../user/project/deploy_tokens/index.md#gitlab-deploy-token
......@@ -71,6 +71,16 @@ docker login registry.example.com -u <username> -p <deploy_token>
Just replace `<username>` and `<deploy_token>` with the proper values. Then you can simply
pull images from your Container Registry.
### GitLab Deploy Token
> [Introduced][ce-18414] in GitLab 10.8.
There's a special case when it comes to Deploy Tokens, if a user creates one
named `gitlab-deploy-token`, the name and token of the Deploy Token will be
automatically exposed to the CI/CD jobs as environment variables: `CI_DEPLOY_USER` and
`CI_DEPLOY_PASSWORD`, respectively.
[ce-17894]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/17894
[ce-11845]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/11845
[ce-18414]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/18414
[container registry]: ../container_registry.md
......@@ -10,5 +10,13 @@ FactoryBot.define do
trait :revoked do
revoked true
end
trait :gitlab_deploy_token do
name DeployToken::GITLAB_DEPLOY_TOKEN_NAME
end
trait :expired do
expires_at { Date.today - 1.month }
end
end
end
......@@ -2035,6 +2035,34 @@ describe Ci::Build do
expect(build).not_to be_persisted
end
end
context 'for deploy tokens' do
let(:deploy_token) { create(:deploy_token, :gitlab_deploy_token) }
let(:deploy_token_variables) do
[
{ key: 'CI_DEPLOY_USER', value: deploy_token.name, public: true },
{ key: 'CI_DEPLOY_PASSWORD', value: deploy_token.token, public: false }
]
end
context 'when gitlab-deploy-token exists' do
before do
project.deploy_tokens << deploy_token
end
it 'should include deploy token variables' do
is_expected.to include(*deploy_token_variables)
end
end
context 'when gitlab-deploy-token does not exist' do
it 'should not include deploy token variables' do
expect(subject.find { |v| v[:key] == 'CI_DEPLOY_USER'}).to be_nil
expect(subject.find { |v| v[:key] == 'CI_DEPLOY_PASSWORD'}).to be_nil
end
end
end
end
describe '#scoped_variables' do
......@@ -2083,7 +2111,9 @@ describe Ci::Build do
CI_REGISTRY_USER
CI_REGISTRY_PASSWORD
CI_REPOSITORY_URL
CI_ENVIRONMENT_URL]
CI_ENVIRONMENT_URL
CI_DEPLOY_USER
CI_DEPLOY_PASSWORD]
build.scoped_variables.map { |env| env[:key] }.tap do |names|
expect(names).not_to include(*keys)
......
......@@ -142,4 +142,23 @@ describe DeployToken do
end
end
end
describe '.gitlab_deploy_token' do
let(:project) { create(:project ) }
subject { project.deploy_tokens.gitlab_deploy_token }
context 'with a gitlab deploy token associated' do
it 'should return the gitlab deploy token' do
deploy_token = create(:deploy_token, :gitlab_deploy_token, projects: [project])
is_expected.to eq(deploy_token)
end
end
context 'with no gitlab deploy token associated' do
it 'should return nil' do
is_expected.to be_nil
end
end
end
end
......@@ -3585,4 +3585,44 @@ describe Project do
it { is_expected.not_to be_valid }
end
end
describe '#gitlab_deploy_token' do
let(:project) { create(:project) }
subject { project.gitlab_deploy_token }
context 'when there is a gitlab deploy token associated' do
let!(:deploy_token) { create(:deploy_token, :gitlab_deploy_token, projects: [project]) }
it { is_expected.to eq(deploy_token) }
end
context 'when there is no a gitlab deploy token associated' do
it { is_expected.to be_nil }
end
context 'when there is a gitlab deploy token associated but is has been revoked' do
let!(:deploy_token) { create(:deploy_token, :gitlab_deploy_token, :revoked, projects: [project]) }
it { is_expected.to be_nil }
end
context 'when there is a gitlab deploy token associated but it is expired' do
let!(:deploy_token) { create(:deploy_token, :gitlab_deploy_token, :expired, projects: [project]) }
it { is_expected.to be_nil }
end
context 'when there is a deploy token associated with a different name' do
let!(:deploy_token) { create(:deploy_token, projects: [project]) }
it { is_expected.to be_nil }
end
context 'when there is a deploy token associated to a different project' do
let(:project_2) { create(:project) }
let!(:deploy_token) { create(:deploy_token, projects: [project_2]) }
it { is_expected.to be_nil }
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment