Commit 2aa758a7 authored by Lin Jen-Shin's avatar Lin Jen-Shin

Rename scope to environment_scope

parent 7afa0877
......@@ -53,6 +53,6 @@ class Projects::VariablesController < Projects::ApplicationController
end
def variable_params_ee
%i[scope]
%i[environment_scope]
end
end
......@@ -5,7 +5,7 @@ module EE
module VariableClassMethods
def key_uniqueness_scope
%i[project_id scope]
%i[project_id environment_scope]
end
end
......@@ -13,10 +13,10 @@ module EE
singleton_class.prepend(VariableClassMethods)
validates(
:scope,
:environment_scope,
presence: true,
format: { with: ::Gitlab::Regex.variable_scope_regex,
message: ::Gitlab::Regex.variable_scope_regex_message }
format: { with: ::Gitlab::Regex.environment_scope_regex,
message: ::Gitlab::Regex.environment_scope_regex_message }
)
end
end
......
......@@ -78,20 +78,20 @@ module EE
end
def secret_variables_for(ref:, environment: nil)
return super.where(scope: '*') unless environment
return super.where(environment_scope: '*') unless environment
query = super
where = <<~SQL
scope IN (:wildcard, :environment_name) OR
environment_scope IN (:wildcard, :environment_name) OR
:environment_name LIKE
REPLACE(REPLACE(scope, :wildcard, :percent),
REPLACE(REPLACE(environment_scope, :wildcard, :percent),
:underscore,
:escaped_underscore)
SQL
order = <<~SQL
CASE scope
CASE environment_scope
WHEN %{wildcard} THEN 0
WHEN %{environment_name} THEN 2
ELSE 1
......
......@@ -8,12 +8,12 @@
= f.label :value, "Value", class: "label-light"
= f.text_area :value, class: "form-control", placeholder: "PROJECT_VARIABLE"
.form-group
= f.label :scope, "Scope", class: "label-light"
= f.text_field :scope, class: "form-control", placeholder: "*"
= f.label :environment_scope, "Environment scope", class: "label-light"
= f.text_field :environment_scope, class: "form-control", placeholder: "*"
.help-block
This variable will be passed only to jobs with a matching environment name.
<code>*</code> is a wildcard that matches all environments (existing or not).
= link_to icon('question-circle'), help_page_path('ci/variables/README', anchor: 'limiting-scopes-of-secret-variables'), target: '_blank'
= link_to icon('question-circle'), help_page_path('ci/variables/README', anchor: 'limiting-environment-scopes-of-secret-variables'), target: '_blank'
.form-group
.checkbox
= f.label :protected do
......
......@@ -9,7 +9,7 @@
%th Key
%th Value
%th Protected
%th Scope
%th Environment scope
%th
%tbody
- @project.variables.order_key_asc.each do |variable|
......@@ -18,7 +18,7 @@
%td.variable-key= variable.key
%td.variable-value{ "data-value" => variable.value }******
%td.variable-protected= Gitlab::Utils.boolean_to_yes_no(variable.protected)
%td.variable-scope= variable.scope
%td.variable-environment-scope= variable.environment_scope
%td.variable-menu
= link_to namespace_project_variable_path(@project.namespace, @project, variable), class: "btn btn-transparent btn-variable-edit" do
%span.sr-only
......
---
title: Add scope to secret variables to specify environments
title: Add environment scope to secret variables to specify environments
merge_request: 2112
author:
class AddScopeToCiVariables < ActiveRecord::Migration
class AddEnvironmentScopeToCiVariables < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
......@@ -6,10 +6,10 @@ class AddScopeToCiVariables < ActiveRecord::Migration
disable_ddl_transaction!
def up
add_column_with_default(:ci_variables, :scope, :string, default: '*')
add_column_with_default(:ci_variables, :environment_scope, :string, default: '*')
end
def down
remove_column(:ci_variables, :scope)
remove_column(:ci_variables, :environment_scope)
end
end
......@@ -440,7 +440,7 @@ ActiveRecord::Schema.define(version: 20170612150426) do
t.string "encrypted_value_iv"
t.integer "project_id", null: false
t.boolean "protected", default: false, null: false
t.string "scope", default: "*", null: false
t.string "environment_scope", default: "*", null: false
end
add_index "ci_variables", ["project_id"], name: "index_ci_variables_on_project_id", using: :btree
......
......@@ -67,7 +67,7 @@ POST /projects/:id/variables
| `key` | string | yes | The `key` of a variable; must have no more than 255 characters; only `A-Z`, `a-z`, `0-9`, and `_` are allowed |
| `value` | string | yes | The `value` of a variable |
| `protected` | boolean | no | Whether the variable is protected |
| `scope` | string | no | The `scope` of the variable |
| `environment_scope` | string | no | The `environment_scope` of the variable |
```
curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v4/projects/1/variables" --form "key=NEW_VARIABLE" --form "value=new value"
......@@ -78,7 +78,7 @@ curl --request POST --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitl
"key": "NEW_VARIABLE",
"value": "new value",
"protected": false,
"scope": "*"
"environment_scope": "*"
}
```
......@@ -96,7 +96,7 @@ PUT /projects/:id/variables/:key
| `key` | string | yes | The `key` of a variable |
| `value` | string | yes | The `value` of a variable |
| `protected` | boolean | no | Whether the variable is protected |
| `scope` | string | no | The `scope` of the variable |
| `environment_scope` | string | no | The `environment_scope` of the variable |
```
curl --request PUT --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v4/projects/1/variables/NEW_VARIABLE" --form "value=updated value"
......@@ -107,7 +107,7 @@ curl --request PUT --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitla
"key": "NEW_VARIABLE",
"value": "updated value",
"protected": true,
"scope": "*"
"environment_scope": "*"
}
```
......
......@@ -176,22 +176,23 @@ Protected variables can be added by going to your project's
Once you set them, they will be available for all subsequent pipelines.
### Limiting scopes of secret variables
### Limiting environment scopes of secret variables
>**Notes:**
[Introduced][ee-2112] in [GitLab Enterprise Edition Premium][eep] 9.4.
You can limit the scope of a secret variable by [defining which environments][envs]
it can be available for.
You can limit the environment scope of a secret variable by
[defining which environments][envs] it can be available for.
Wildcards can be used, and the default scope is `*` which means any jobs will
have this variable, not matter if an environment is defined or not.
Wildcards can be used, and the default environment scope is `*` which means
any jobs will have this variable, not matter if an environment is defined or
not.
For example, if the scope is `production`, then only the jobs having the
environment `production` defined would have this specific variable. Wildcards (`*`)
can be used along with the environment name, therefore if the scope is `review/*`
then any jobs with environment names starting with `review/` would have
that particular variable.
For example, if the environment scope is `production`, then only the jobs
having the environment `production` defined would have this specific variable.
Wildcards (`*`) can be used along with the environment name, therefore if the
environment scope is `review/*` then any jobs with environment names starting
with `review/` would have that particular variable.
## Deployment variables
......
......@@ -753,7 +753,7 @@ module API
expose :protected?, as: :protected
# EE
expose :scope
expose :environment_scope
end
class Pipeline < PipelineBasic
......
......@@ -45,7 +45,7 @@ module API
optional :protected, type: String, desc: 'Whether the variable is protected'
# EE
optional :scope, type: String, desc: 'The scope of the variable'
optional :environment_scope, type: String, desc: 'The environment_scope of the variable'
end
post ':id/variables' do
variable = user_project.variables.create(declared_params(include_missing: false))
......@@ -66,7 +66,7 @@ module API
optional :protected, type: String, desc: 'Whether the variable is protected'
# EE
optional :scope, type: String, desc: 'The scope of the variable'
optional :environment_scope, type: String, desc: 'The environment_scope of the variable'
end
put ':id/variables/:key' do
variable = user_project.variables.find_by(key: params[:key])
......
module EE
module Gitlab
module Regex
def variable_scope_regex_chars
def environment_scope_regex_chars
"#{environment_name_regex_chars}\\*"
end
def variable_scope_regex
@variable_scope_regex ||= /\A[#{variable_scope_regex_chars}]+\z/.freeze
def environment_scope_regex
@environment_scope_regex ||= /\A[#{environment_scope_regex_chars}]+\z/.freeze
end
def variable_scope_regex_message
def environment_scope_regex_message
"can contain only letters, digits, '-', '_', '/', '$', '{', '}', '.', '*' and spaces"
end
end
......
......@@ -56,10 +56,10 @@ describe 'Project variables', js: true do
end
# EE
it 'adds new variable with a special scope' do
it 'adds new variable with a special environment scope' do
fill_in('variable_key', with: 'key')
fill_in('variable_value', with: 'value')
fill_in('variable_scope', with: 'review/*')
fill_in('variable_environment_scope', with: 'review/*')
click_button('Add new variable')
expect(page).to have_content('Variables were successfully updated.')
......@@ -158,16 +158,16 @@ describe 'Project variables', js: true do
end
# EE
it 'edits variable to be another scope' do
it 'edits variable to be another environment scope' do
page.within('.variables-table') do
find('.btn-variable-edit').click
end
expect(page).to have_content('Update variable')
fill_in('variable_scope', with: 'review/*')
fill_in('variable_environment_scope', with: 'review/*')
click_button('Save variable')
expect(page).to have_content('Variable was successfully updated.')
expect(project.variables(true).first.scope).to eq('review/*')
expect(project.variables(true).first.environment_scope).to eq('review/*')
end
end
......@@ -1417,7 +1417,7 @@ describe Ci::Build, :models do
create(:ci_variable,
environment_varialbe.slice(:key, :value)
.merge(project: project, scope: 'stag*'))
.merge(project: project, environment_scope: 'stag*'))
end
it { is_expected.to include(environment_varialbe) }
......
......@@ -12,11 +12,11 @@ describe Ci::Variable, models: true do
it { is_expected.not_to allow_value('foo/bar').for(:key) }
# EE
it { is_expected.to allow_value('review/*').for(:scope) }
it { is_expected.not_to allow_value('').for(:scope) }
it { is_expected.to allow_value('review/*').for(:environment_scope) }
it { is_expected.not_to allow_value('').for(:environment_scope) }
let(:key_scope) do
[:project_id, :scope] # EE
[:project_id, :environment_scope] # EE
end
it { is_expected.to validate_uniqueness_of(:key).scoped_to(key_scope) }
......
......@@ -2293,9 +2293,9 @@ describe Project, models: true do
project.secret_variables_for(ref: 'ref', environment: environment)
end
context 'when scope is exactly matched' do
context 'when environment scope is exactly matched' do
before do
secret_variable.update(scope: 'review/name')
secret_variable.update(environment_scope: 'review/name')
end
it 'contains the secret variable' do
......@@ -2303,9 +2303,9 @@ describe Project, models: true do
end
end
context 'when scope is matched by wildcard' do
context 'when environment scope is matched by wildcard' do
before do
secret_variable.update(scope: 'review/*')
secret_variable.update(environment_scope: 'review/*')
end
it 'contains the secret variable' do
......@@ -2313,9 +2313,9 @@ describe Project, models: true do
end
end
context 'when scope does not match' do
context 'when environment scope does not match' do
before do
secret_variable.update(scope: 'review/*/special')
secret_variable.update(environment_scope: 'review/*/special')
end
it 'does not contain the secret variable' do
......@@ -2323,27 +2323,27 @@ describe Project, models: true do
end
end
context 'when scope has _' do
context 'when environment scope has _' do
it 'does not treat it as wildcard' do
secret_variable.update(scope: '*_*')
secret_variable.update(environment_scope: '*_*')
is_expected.not_to contain_exactly(secret_variable)
end
it 'matches literally for _' do
secret_variable.update(scope: 'foo_bar/*')
secret_variable.update(environment_scope: 'foo_bar/*')
environment.update(name: 'foo_bar/test')
is_expected.to contain_exactly(secret_variable)
end
end
context 'when variables with the same name have different scopes' do
context 'when variables with the same name have different environment scopes' do
let!(:partially_matched_variable) do
create(:ci_variable,
key: secret_variable.key,
value: 'partial',
scope: 'review/*',
environment_scope: 'review/*',
project: project)
end
......@@ -2351,11 +2351,11 @@ describe Project, models: true do
create(:ci_variable,
key: secret_variable.key,
value: 'prefect',
scope: 'review/name',
environment_scope: 'review/name',
project: project)
end
it 'puts variables matching scope more in the end' do
it 'puts variables matching environment scope more in the end' do
is_expected.to eq(
[secret_variable,
partially_matched_variable,
......
......@@ -91,27 +91,27 @@ describe API::Variables do
end
# EE
it 'creates variable with a specific scope' do
it 'creates variable with a specific environment scope' do
expect do
post api("/projects/#{project.id}/variables", user), key: 'TEST_VARIABLE_2', value: 'VALUE_2', scope: 'review/*'
post api("/projects/#{project.id}/variables", user), key: 'TEST_VARIABLE_2', value: 'VALUE_2', environment_scope: 'review/*'
end.to change{project.variables.count}.by(1)
expect(response).to have_http_status(201)
expect(json_response['key']).to eq('TEST_VARIABLE_2')
expect(json_response['value']).to eq('VALUE_2')
expect(json_response['scope']).to eq('review/*')
expect(json_response['environment_scope']).to eq('review/*')
end
# EE
it 'allows duplicated variable key given different scopes' do
it 'allows duplicated variable key given different environment scopes' do
expect do
post api("/projects/#{project.id}/variables", user), key: variable.key, value: 'VALUE_2', scope: 'review/*'
post api("/projects/#{project.id}/variables", user), key: variable.key, value: 'VALUE_2', environment_scope: 'review/*'
end.to change{project.variables.count}.by(1)
expect(response).to have_http_status(201)
expect(json_response['key']).to eq(variable.key)
expect(json_response['value']).to eq('VALUE_2')
expect(json_response['scope']).to eq('review/*')
expect(json_response['environment_scope']).to eq('review/*')
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