Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorGrzegorz Bizon <grzegorz@gitlab.com>2019-01-07 12:19:36 +0300
committerGrzegorz Bizon <grzegorz@gitlab.com>2019-01-07 12:19:36 +0300
commit604073ffc38f938e36f613c592c444d56c99f49c (patch)
treea741c7e6bb3dd9d189be82c7f4c0e8147f19dd89 /lib
parent301315f3b3e5ffe43c3de1f7f15e4e3a307c0912 (diff)
parentc4d615c9dcba6815d0e9d1b7b7de5b7528ac7c72 (diff)
Merge branch 'include-project' into 'master'
Allow to include another project files Closes #53903 See merge request gitlab-org/gitlab-ce!24101
Diffstat (limited to 'lib')
-rw-r--r--lib/api/lint.rb3
-rw-r--r--lib/gitlab/ci/config.rb17
-rw-r--r--lib/gitlab/ci/config/external/file/base.rb2
-rw-r--r--lib/gitlab/ci/config/external/file/project.rb72
-rw-r--r--lib/gitlab/ci/config/external/mapper.rb8
-rw-r--r--lib/gitlab/ci/config/external/processor.rb4
-rw-r--r--lib/gitlab/ci/yaml_processor.rb2
7 files changed, 92 insertions, 16 deletions
diff --git a/lib/api/lint.rb b/lib/api/lint.rb
index 0342a4b6654..a7672021db0 100644
--- a/lib/api/lint.rb
+++ b/lib/api/lint.rb
@@ -8,7 +8,8 @@ module API
requires :content, type: String, desc: 'Content of .gitlab-ci.yml'
end
post '/lint' do
- error = Gitlab::Ci::YamlProcessor.validation_message(params[:content])
+ error = Gitlab::Ci::YamlProcessor.validation_message(params[:content],
+ user: current_user)
status 200
diff --git a/lib/gitlab/ci/config.rb b/lib/gitlab/ci/config.rb
index 11e0352975d..5875479183e 100644
--- a/lib/gitlab/ci/config.rb
+++ b/lib/gitlab/ci/config.rb
@@ -8,9 +8,9 @@ module Gitlab
class Config
ConfigError = Class.new(StandardError)
- def initialize(config, opts = {})
+ def initialize(config, project: nil, sha: nil, user: nil)
@config = Config::Extendable
- .new(build_config(config, opts))
+ .new(build_config(config, project: project, sha: sha, user: user))
.to_hash
@global = Entry::Global.new(@config)
@@ -70,20 +70,21 @@ module Gitlab
private
- def build_config(config, opts = {})
+ def build_config(config, project:, sha:, user:)
initial_config = Gitlab::Config::Loader::Yaml.new(config).load!
- project = opts.fetch(:project, nil)
if project
- process_external_files(initial_config, project, opts)
+ process_external_files(initial_config, project: project, sha: sha, user: user)
else
initial_config
end
end
- def process_external_files(config, project, opts)
- sha = opts.fetch(:sha) { project.repository.root_ref_sha }
- Config::External::Processor.new(config, project: project, sha: sha).perform
+ def process_external_files(config, project:, sha:, user:)
+ Config::External::Processor.new(config,
+ project: project,
+ sha: sha || project.repository.root_ref_sha,
+ user: user).perform
end
end
end
diff --git a/lib/gitlab/ci/config/external/file/base.rb b/lib/gitlab/ci/config/external/file/base.rb
index 2ac6656a703..a747886093c 100644
--- a/lib/gitlab/ci/config/external/file/base.rb
+++ b/lib/gitlab/ci/config/external/file/base.rb
@@ -12,7 +12,7 @@ module Gitlab
YAML_WHITELIST_EXTENSION = /.+\.(yml|yaml)$/i.freeze
- Context = Struct.new(:project, :sha)
+ Context = Struct.new(:project, :sha, :user)
def initialize(params, context)
@params = params
diff --git a/lib/gitlab/ci/config/external/file/project.rb b/lib/gitlab/ci/config/external/file/project.rb
new file mode 100644
index 00000000000..e75540dbe5a
--- /dev/null
+++ b/lib/gitlab/ci/config/external/file/project.rb
@@ -0,0 +1,72 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Ci
+ class Config
+ module External
+ module File
+ class Project < Base
+ include Gitlab::Utils::StrongMemoize
+
+ attr_reader :project_name, :ref_name
+
+ def initialize(params, context = {})
+ @location = params[:file]
+ @project_name = params[:project]
+ @ref_name = params[:ref] || 'HEAD'
+
+ super
+ end
+
+ def matching?
+ super && project_name.present?
+ end
+
+ def content
+ strong_memoize(:content) { fetch_local_content }
+ end
+
+ private
+
+ def validate_content!
+ if !can_access_local_content?
+ errors.push("Project `#{project_name}` not found or access denied!")
+ elsif sha.nil?
+ errors.push("Project `#{project_name}` reference `#{ref_name}` does not exist!")
+ elsif content.nil?
+ errors.push("Project `#{project_name}` file `#{location}` does not exist!")
+ elsif content.blank?
+ errors.push("Project `#{project_name}` file `#{location}` is empty!")
+ end
+ end
+
+ def project
+ strong_memoize(:project) do
+ ::Project.find_by_full_path(project_name)
+ end
+ end
+
+ def can_access_local_content?
+ Ability.allowed?(context.user, :download_code, project)
+ end
+
+ def fetch_local_content
+ return unless can_access_local_content?
+ return unless sha
+
+ project.repository.blob_data_at(sha, location)
+ rescue GRPC::NotFound, GRPC::Internal
+ nil
+ end
+
+ def sha
+ strong_memoize(:sha) do
+ project.commit(ref_name).try(:sha)
+ end
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/config/external/mapper.rb b/lib/gitlab/ci/config/external/mapper.rb
index 74bd927da39..108bfd5eb43 100644
--- a/lib/gitlab/ci/config/external/mapper.rb
+++ b/lib/gitlab/ci/config/external/mapper.rb
@@ -10,15 +10,17 @@ module Gitlab
FILE_CLASSES = [
External::File::Remote,
External::File::Template,
- External::File::Local
+ External::File::Local,
+ External::File::Project
].freeze
AmbigiousSpecificationError = Class.new(StandardError)
- def initialize(values, project:, sha:)
+ def initialize(values, project:, sha:, user:)
@locations = Array.wrap(values.fetch(:include, []))
@project = project
@sha = sha
+ @user = user
end
def process
@@ -61,7 +63,7 @@ module Gitlab
def context
strong_memoize(:context) do
- External::File::Base::Context.new(project, sha)
+ External::File::Base::Context.new(project, sha, user)
end
end
end
diff --git a/lib/gitlab/ci/config/external/processor.rb b/lib/gitlab/ci/config/external/processor.rb
index 1d310b29dc8..69bc164a039 100644
--- a/lib/gitlab/ci/config/external/processor.rb
+++ b/lib/gitlab/ci/config/external/processor.rb
@@ -7,9 +7,9 @@ module Gitlab
class Processor
IncludeError = Class.new(StandardError)
- def initialize(values, project:, sha:)
+ def initialize(values, project:, sha:, user:)
@values = values
- @external_files = External::Mapper.new(values, project: project, sha: sha).process
+ @external_files = External::Mapper.new(values, project: project, sha: sha, user: user).process
@content = {}
rescue External::Mapper::AmbigiousSpecificationError => e
raise IncludeError, e.message
diff --git a/lib/gitlab/ci/yaml_processor.rb b/lib/gitlab/ci/yaml_processor.rb
index 15097188061..0c48a6ab3ac 100644
--- a/lib/gitlab/ci/yaml_processor.rb
+++ b/lib/gitlab/ci/yaml_processor.rb
@@ -10,7 +10,7 @@ module Gitlab
attr_reader :cache, :stages, :jobs
def initialize(config, opts = {})
- @ci_config = Gitlab::Ci::Config.new(config, opts)
+ @ci_config = Gitlab::Ci::Config.new(config, **opts)
@config = @ci_config.to_hash
unless @ci_config.valid?