Commit c3c9032b authored by Lin Jen-Shin's avatar Lin Jen-Shin

Check if the feature is available

parent af207c15
......@@ -22,9 +22,9 @@ class Projects::VariablesController < Projects::ApplicationController
end
def create
@variable = Ci::Variable.new(variable_params)
@variable = @project.variables.new(variable_params)
if @variable.valid? && @project.variables << @variable
if @variable.save
flash[:notice] = 'Variables were successfully updated.'
redirect_to namespace_project_settings_ci_cd_path(project.namespace, project)
else
......
......@@ -18,6 +18,18 @@ module EE
format: { with: ::Gitlab::Regex.environment_scope_regex,
message: ::Gitlab::Regex.environment_scope_regex_message }
)
validate :updating_environment_scope
private
def updating_environment_scope
return unless environment_scope_changed?
unless project.feature_available?(:variable_environment_scope)
errors.add(:environment_scope, 'is not enabled for this project')
end
end
end
end
end
......
......@@ -78,7 +78,8 @@ module EE
end
def secret_variables_for(ref:, environment: nil)
return super.where(environment_scope: '*') unless environment
return super.where(environment_scope: '*') unless
environment && feature_available?(:variable_environment_scope)
query = super
......
......@@ -9,6 +9,7 @@ class License < ActiveRecord::Base
OBJECT_STORAGE_FEATURE = 'GitLab_ObjectStorage'.freeze
ELASTIC_SEARCH_FEATURE = 'GitLab_ElasticSearch'.freeze
RELATED_ISSUES_FEATURE = 'RelatedIssues'.freeze
VARIABLE_ENVIRONMENT_SCOPE_FEATURE = 'GitLab_VARIABLE_ENVIRONMENT_SCOPE'.freeze
FEATURE_CODES = {
geo: GEO_FEATURE,
......@@ -17,6 +18,7 @@ class License < ActiveRecord::Base
object_storage: OBJECT_STORAGE_FEATURE,
elastic_search: ELASTIC_SEARCH_FEATURE,
related_issues: RELATED_ISSUES_FEATURE,
variable_environment_scope: VARIABLE_ENVIRONMENT_SCOPE_FEATURE,
# Features that make sense to Namespace:
deploy_board: DEPLOY_BOARD_FEATURE,
file_lock: FILE_LOCK_FEATURE
......@@ -39,7 +41,8 @@ class License < ActiveRecord::Base
{ GEO_FEATURE => 1 },
{ AUDITOR_USER_FEATURE => 1 },
{ SERVICE_DESK_FEATURE => 1 },
{ OBJECT_STORAGE_FEATURE => 1 }
{ OBJECT_STORAGE_FEATURE => 1 },
{ VARIABLE_ENVIRONMENT_SCOPE_FEATURE => 1 }
].freeze
EEU_FEATURES = [
......
%h4.prepend-top-0
Secret variables
= link_to icon('question-circle'), help_page_path('ci/variables/README', anchor: 'secret-variables'), target: '_blank'
%p
These variables will be set to environment by the runner, and could be protected by exposing only to protected branches or tags, or some particular environments.
- if @project.feature_available?(:variable_environment_scope)
%p
These variables will be set to environment by the runner, and could be protected by exposing only to protected branches or tags, or some particular environments.
- else
%p
These variables will be set to environment by the runner, and could be protected by exposing only to protected branches or tags.
%p
So you can use them for passwords, secret keys or whatever you want.
%p
......
......@@ -7,13 +7,14 @@
.form-group
= f.label :value, "Value", class: "label-light"
= f.text_area :value, class: "form-control", placeholder: "PROJECT_VARIABLE"
.form-group
= 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-environment-scopes-of-secret-variables'), target: '_blank'
- if @project.feature_available?(:variable_environment_scope)
.form-group
= 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-environment-scopes-of-secret-variables'), target: '_blank'
.form-group
.checkbox
= f.label :protected do
......
......@@ -9,7 +9,8 @@
%th Key
%th Value
%th Protected
%th Environment scope
- if @project.feature_available?(:variable_environment_scope)
%th Environment scope
%th
%tbody
- @project.variables.order_key_asc.each do |variable|
......@@ -18,7 +19,8 @@
%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-environment-scope= variable.environment_scope
- if @project.feature_available?(:variable_environment_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
......
......@@ -753,7 +753,9 @@ module API
expose :protected?, as: :protected
# EE
expose :environment_scope
expose :environment_scope, if: ->(variable, options) {
variable.project.feature_available?(:variable_environment_scope)
}
end
class Pipeline < PipelineBasic
......
......@@ -6,6 +6,9 @@ describe 'Project variables', js: true do
let(:variable) { create(:ci_variable, key: 'test_key', value: 'test value') }
before do
# EE
stub_feature(:variable_environment_scope)
login_as(user)
project.team << [user, :master]
project.variables << variable
......
......@@ -2,8 +2,7 @@ require 'spec_helper'
describe EE::Gitlab::ServiceDesk, lib: true do
before do
allow_any_instance_of(License).to receive(:feature_available?).and_call_original
allow_any_instance_of(License).to receive(:feature_available?).with(:service_desk) { true }
stub_feature(:service_desk)
allow(::Gitlab::IncomingEmail).to receive(:enabled?) { true }
allow(::Gitlab::IncomingEmail).to receive(:supports_wildcard?) { true }
end
......
......@@ -1412,6 +1412,8 @@ describe Ci::Build, :models do
end
before do
stub_feature(:variable_environment_scope)
build.update(environment: 'staging')
create(:environment, name: 'staging', project: build.project)
......
......@@ -12,8 +12,14 @@ 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(:environment_scope) }
it { is_expected.not_to allow_value('').for(:environment_scope) }
context 'with variable_environment_scope enabled' do
before do
stub_feature(:variable_environment_scope)
end
it { is_expected.to allow_value('review/*').for(:environment_scope) }
it { is_expected.not_to allow_value('').for(:environment_scope) }
end
let(:key_scope) do
[:project_id, :environment_scope] # EE
......
......@@ -2293,6 +2293,10 @@ describe Project, models: true do
project.secret_variables_for(ref: 'ref', environment: environment)
end
before do
stub_feature(:variable_environment_scope)
end
context 'when environment scope is exactly matched' do
before do
secret_variable.update(environment_scope: 'review/name')
......
......@@ -92,6 +92,8 @@ describe API::Variables do
# EE
it 'creates variable with a specific environment scope' do
stub_feature(:variable_environment_scope)
expect do
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)
......@@ -104,6 +106,8 @@ describe API::Variables do
# EE
it 'allows duplicated variable key given different environment scopes' do
stub_feature(:variable_environment_scope)
expect do
post api("/projects/#{project.id}/variables", user), key: variable.key, value: 'VALUE_2', environment_scope: 'review/*'
end.to change{project.variables.count}.by(1)
......
......@@ -57,6 +57,7 @@ RSpec.configure do |config|
config.include StubGitlabData
config.include ApiHelpers, :api
config.include MigrationsHelpers, :migration
config.include EE::LicenseHelpers
config.include Rails.application.routes.url_helpers, type: :routing
config.infer_spec_type_from_file_location!
......
module EE
module LicenseHelpers
def stub_feature(feature, enabled = true)
allow_any_instance_of(License).to receive(:feature_available?)
.and_call_original
allow_any_instance_of(License).to receive(:feature_available?)
.with(feature) { enabled }
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