Commit b1120fc3 authored by Kamil Trzciński's avatar Kamil Trzciński

Merge branch 'expose-deployment-variables' into 'master'

Pass variables from deployment project services to CI runner

## What does this MR do?

This commit introduces the concept of deployment variables - variables
that are collected from deployment services and passed to CI runner
during a deployment build.
Deployment services specify the variables by overriding
"predefined_variables" method.

This commit also configures variables for KubernetesService

## Why was this MR needed?

We need these values for https://gitlab.com/gitlab-org/gitlab-ce/issues/23580

## Does this MR meet the acceptance criteria?

- [x] [Changelog entry](https://docs.gitlab.com/ce/development/changelog.html) added
- [x] [Documentation created/updated](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/development/doc_styleguide.md)
- ~~[ ] API support added~~
- Tests
  - [x] Added for this feature/bug
  - [ ] All builds are passing
- [x] Conform by the [merge request performance guides](http://docs.gitlab.com/ce/development/merge_request_performance_guidelines.html)
- [x] Conform by the [style guides](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md#style-guides)
- [x] Branch has no merge conflicts with `master` (if it does - rebase it please)
- [x] [Squashed related commits together](https://git-scm.com/book/en/Git-Tools-Rewriting-History#Squashing-Commits)

## What are the relevant issue numbers?

Refers to https://gitlab.com/gitlab-org/gitlab-ce/issues/23580

See merge request !8107
parents ca6bf62e c945a0a7
...@@ -155,7 +155,7 @@ module Ci ...@@ -155,7 +155,7 @@ module Ci
end end
def has_environment? def has_environment?
self.environment.present? environment.present?
end end
def starts_environment? def starts_environment?
...@@ -221,6 +221,7 @@ module Ci ...@@ -221,6 +221,7 @@ module Ci
variables += pipeline.predefined_variables variables += pipeline.predefined_variables
variables += runner.predefined_variables if runner variables += runner.predefined_variables if runner
variables += project.container_registry_variables variables += project.container_registry_variables
variables += project.deployment_variables if has_environment?
variables += yaml_variables variables += yaml_variables
variables += user_variables variables += user_variables
variables += project.secret_variables variables += project.secret_variables
......
...@@ -1230,6 +1230,12 @@ class Project < ActiveRecord::Base ...@@ -1230,6 +1230,12 @@ class Project < ActiveRecord::Base
end end
end end
def deployment_variables
return [] unless deployment_service
deployment_service.predefined_variables
end
def append_or_update_attribute(name, value) def append_or_update_attribute(name, value)
old_values = public_send(name.to_s) old_values = public_send(name.to_s)
......
...@@ -8,4 +8,8 @@ class DeploymentService < Service ...@@ -8,4 +8,8 @@ class DeploymentService < Service
def supported_events def supported_events
[] []
end end
def predefined_variables
[]
end
end end
...@@ -83,6 +83,16 @@ class KubernetesService < DeploymentService ...@@ -83,6 +83,16 @@ class KubernetesService < DeploymentService
{ success: false, result: err } { success: false, result: err }
end end
def predefined_variables
variables = [
{ key: 'KUBE_URL', value: api_url, public: true },
{ key: 'KUBE_TOKEN', value: token, public: false },
{ key: 'KUBE_NAMESPACE', value: namespace, public: true }
]
variables << { key: 'KUBE_CA_PEM', value: ca_pem, public: true } if ca_pem.present?
variables
end
private private
def build_kubeclient(api_path = '/api', api_version = 'v1') def build_kubeclient(api_path = '/api', api_version = 'v1')
......
---
title: Pass variables from deployment project services to CI runner
merge_request: 8107
author:
...@@ -13,6 +13,7 @@ this order: ...@@ -13,6 +13,7 @@ this order:
1. [Secret variables](#secret-variables) 1. [Secret variables](#secret-variables)
1. YAML-defined [job-level variables](../yaml/README.md#job-variables) 1. YAML-defined [job-level variables](../yaml/README.md#job-variables)
1. YAML-defined [global variables](../yaml/README.md#variables) 1. YAML-defined [global variables](../yaml/README.md#variables)
1. [Deployment variables](#deployment-variables)
1. [Predefined variables](#predefined-variables-environment-variables) (are the 1. [Predefined variables](#predefined-variables-environment-variables) (are the
lowest in the chain) lowest in the chain)
...@@ -148,6 +149,20 @@ Secret variables can be added by going to your project's ...@@ -148,6 +149,20 @@ Secret variables can be added by going to your project's
Once you set them, they will be available for all subsequent builds. Once you set them, they will be available for all subsequent builds.
## Deployment variables
>**Note:**
This feature requires GitLab CI 8.15 or higher.
[Project services](../../project_services/project_services.md) that are
responsible for deployment configuration may define their own variables that
are set in the build environment. These variables are only defined for
[deployment builds](../environments.md). Please consult the documentation of
the project services that you are using to learn which variables they define.
An example project service that defines deployment variables is
[Kubernetes Service](../../project_services/kubernetes.md).
## Debug tracing ## Debug tracing
> Introduced in GitLab Runner 1.7. > Introduced in GitLab Runner 1.7.
......
...@@ -36,3 +36,14 @@ to create one. You can also view or create service tokens in the ...@@ -36,3 +36,14 @@ to create one. You can also view or create service tokens in the
Fill in the service token and namespace according to the values you just got. Fill in the service token and namespace according to the values you just got.
If the API is using a self-signed TLS certificate, you'll also need to include If the API is using a self-signed TLS certificate, you'll also need to include
the `ca.crt` contents as the `Custom CA bundle`. the `ca.crt` contents as the `Custom CA bundle`.
## Deployment variables
The Kubernetes service exposes following
[deployment variables](../ci/variables/README.md#deployment-variables) in the
GitLab CI build environment:
- `KUBE_URL` - equal to the API URL
- `KUBE_TOKEN`
- `KUBE_NAMESPACE`
- `KUBE_CA_PEM` - only if a custom CA bundle was specified
...@@ -506,6 +506,17 @@ describe Ci::Build, models: true do ...@@ -506,6 +506,17 @@ describe Ci::Build, models: true do
it { is_expected.to include({ key: 'CI_RUNNER_TAGS', value: 'docker, linux', public: true }) } it { is_expected.to include({ key: 'CI_RUNNER_TAGS', value: 'docker, linux', public: true }) }
end end
context 'when build is for a deployment' do
let(:deployment_variable) { { key: 'KUBERNETES_TOKEN', value: 'TOKEN', public: false } }
before do
build.environment = 'production'
allow(project).to receive(:deployment_variables).and_return([deployment_variable])
end
it { is_expected.to include(deployment_variable) }
end
context 'returns variables in valid order' do context 'returns variables in valid order' do
before do before do
allow(build).to receive(:predefined_variables) { ['predefined'] } allow(build).to receive(:predefined_variables) { ['predefined'] }
......
...@@ -123,4 +123,37 @@ describe KubernetesService, models: true do ...@@ -123,4 +123,37 @@ describe KubernetesService, models: true do
end end
end end
end end
describe '#predefined_variables' do
before do
subject.api_url = 'https://kube.domain.com'
subject.token = 'token'
subject.namespace = 'my-project'
subject.ca_pem = 'CA PEM DATA'
end
it 'sets KUBE_URL' do
expect(subject.predefined_variables).to include(
{ key: 'KUBE_URL', value: 'https://kube.domain.com', public: true }
)
end
it 'sets KUBE_TOKEN' do
expect(subject.predefined_variables).to include(
{ key: 'KUBE_TOKEN', value: 'token', public: false }
)
end
it 'sets KUBE_NAMESPACE' do
expect(subject.predefined_variables).to include(
{ key: 'KUBE_NAMESPACE', value: 'my-project', public: true }
)
end
it 'sets KUBE_CA_PEM' do
expect(subject.predefined_variables).to include(
{ key: 'KUBE_CA_PEM', value: 'CA PEM DATA', public: true }
)
end
end
end end
...@@ -1697,6 +1697,26 @@ describe Project, models: true do ...@@ -1697,6 +1697,26 @@ describe Project, models: true do
end end
end end
describe '#deployment_variables' do
context 'when project has no deployment service' do
let(:project) { create(:empty_project) }
it 'returns an empty array' do
expect(project.deployment_variables).to eq []
end
end
context 'when project has a deployment service' do
let(:project) { create(:kubernetes_project) }
it 'returns variables from this service' do
expect(project.deployment_variables).to include(
{ key: 'KUBE_TOKEN', value: project.kubernetes_service.token, public: false }
)
end
end
end
def enable_lfs def enable_lfs
allow(Gitlab.config.lfs).to receive(:enabled).and_return(true) allow(Gitlab.config.lfs).to receive(:enabled).and_return(true)
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