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
This commit is contained in:
commit
92cb6d6354
|
@ -27,6 +27,7 @@ module Ci
|
||||||
|
|
||||||
has_one :metadata, class_name: 'Ci::BuildMetadata'
|
has_one :metadata, class_name: 'Ci::BuildMetadata'
|
||||||
delegate :timeout, to: :metadata, prefix: true, allow_nil: true
|
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!
|
# 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_USER', value: CI_REGISTRY_USER)
|
||||||
.append(key: 'CI_REGISTRY_PASSWORD', value: token, public: false)
|
.append(key: 'CI_REGISTRY_PASSWORD', value: token, public: false)
|
||||||
.append(key: 'CI_REPOSITORY_URL', value: repo_url, public: false)
|
.append(key: 'CI_REPOSITORY_URL', value: repo_url, public: false)
|
||||||
|
.concat(deploy_token_variables)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -654,6 +656,15 @@ module Ci
|
||||||
end
|
end
|
||||||
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
|
def environment_url
|
||||||
options&.dig(:environment, :url) || persisted_environment&.external_url
|
options&.dig(:environment, :url) || persisted_environment&.external_url
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,6 +4,7 @@ class DeployToken < ActiveRecord::Base
|
||||||
add_authentication_token_field :token
|
add_authentication_token_field :token
|
||||||
|
|
||||||
AVAILABLE_SCOPES = %i(read_repository read_registry).freeze
|
AVAILABLE_SCOPES = %i(read_repository read_registry).freeze
|
||||||
|
GITLAB_DEPLOY_TOKEN_NAME = 'gitlab-deploy-token'.freeze
|
||||||
|
|
||||||
default_value_for(:expires_at) { Forever.date }
|
default_value_for(:expires_at) { Forever.date }
|
||||||
|
|
||||||
|
@ -17,6 +18,10 @@ class DeployToken < ActiveRecord::Base
|
||||||
|
|
||||||
scope :active, -> { where("revoked = false AND expires_at >= NOW()") }
|
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!
|
def revoke!
|
||||||
update!(revoked: true)
|
update!(revoked: true)
|
||||||
end
|
end
|
||||||
|
|
|
@ -1879,6 +1879,10 @@ class Project < ActiveRecord::Base
|
||||||
[]
|
[]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def gitlab_deploy_token
|
||||||
|
@gitlab_deploy_token ||= deploy_tokens.gitlab_deploy_token
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def storage
|
def storage
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
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_REGISTRY_PASSWORD`
|
||||||
- `CI_REPOSITORY_URL`
|
- `CI_REPOSITORY_URL`
|
||||||
- `CI_ENVIRONMENT_URL`
|
- `CI_ENVIRONMENT_URL`
|
||||||
|
- `CI_DEPLOY_USER`
|
||||||
|
- `CI_DEPLOY_PASSWORD`
|
||||||
|
|
||||||
GitLab Runner exposes various [environment variables][variables] when a job runs,
|
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
|
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_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 |
|
| **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 |
|
| **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
|
## 9.0 Renaming
|
||||||
|
|
||||||
|
@ -546,6 +548,8 @@ You can find a full list of unsupported variables below:
|
||||||
- `CI_REGISTRY_PASSWORD`
|
- `CI_REGISTRY_PASSWORD`
|
||||||
- `CI_REPOSITORY_URL`
|
- `CI_REPOSITORY_URL`
|
||||||
- `CI_ENVIRONMENT_URL`
|
- `CI_ENVIRONMENT_URL`
|
||||||
|
- `CI_DEPLOY_USER`
|
||||||
|
- `CI_DEPLOY_PASSWORD`
|
||||||
|
|
||||||
These variables are also not supported in a contex of a
|
These variables are also not supported in a contex of a
|
||||||
[dynamic environment name][dynamic-environments].
|
[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
|
[subgroups]: ../../user/group/subgroups/index.md
|
||||||
[builds-policies]: ../yaml/README.md#only-and-except-complex
|
[builds-policies]: ../yaml/README.md#only-and-except-complex
|
||||||
[dynamic-environments]: ../environments.md#dynamic-environments
|
[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
|
Just replace `<username>` and `<deploy_token>` with the proper values. Then you can simply
|
||||||
pull images from your Container Registry.
|
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-17894]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/17894
|
||||||
[ce-11845]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/11845
|
[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
|
[container registry]: ../container_registry.md
|
||||||
|
|
|
@ -10,5 +10,13 @@ FactoryBot.define do
|
||||||
trait :revoked do
|
trait :revoked do
|
||||||
revoked true
|
revoked true
|
||||||
end
|
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
|
||||||
end
|
end
|
||||||
|
|
|
@ -2035,6 +2035,34 @@ describe Ci::Build do
|
||||||
expect(build).not_to be_persisted
|
expect(build).not_to be_persisted
|
||||||
end
|
end
|
||||||
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
|
end
|
||||||
|
|
||||||
describe '#scoped_variables' do
|
describe '#scoped_variables' do
|
||||||
|
@ -2083,7 +2111,9 @@ describe Ci::Build do
|
||||||
CI_REGISTRY_USER
|
CI_REGISTRY_USER
|
||||||
CI_REGISTRY_PASSWORD
|
CI_REGISTRY_PASSWORD
|
||||||
CI_REPOSITORY_URL
|
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|
|
build.scoped_variables.map { |env| env[:key] }.tap do |names|
|
||||||
expect(names).not_to include(*keys)
|
expect(names).not_to include(*keys)
|
||||||
|
|
|
@ -142,4 +142,23 @@ describe DeployToken do
|
||||||
end
|
end
|
||||||
end
|
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
|
end
|
||||||
|
|
|
@ -3585,4 +3585,44 @@ describe Project do
|
||||||
it { is_expected.not_to be_valid }
|
it { is_expected.not_to be_valid }
|
||||||
end
|
end
|
||||||
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
|
end
|
||||||
|
|
Loading…
Reference in New Issue