187 lines
7.3 KiB
Ruby
187 lines
7.3 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
module Gitlab
|
|
module Ci
|
|
module Variables
|
|
class Builder
|
|
include ::Gitlab::Utils::StrongMemoize
|
|
|
|
def initialize(pipeline)
|
|
@pipeline = pipeline
|
|
@pipeline_variables_builder = Builder::Pipeline.new(pipeline)
|
|
@instance_variables_builder = Builder::Instance.new
|
|
@project_variables_builder = Builder::Project.new(project)
|
|
@group_variables_builder = Builder::Group.new(project&.group)
|
|
@release_variables_builder = Builder::Release.new(release)
|
|
end
|
|
|
|
def scoped_variables(job, environment:, dependencies:)
|
|
Gitlab::Ci::Variables::Collection.new.tap do |variables|
|
|
variables.concat(predefined_variables(job))
|
|
variables.concat(project.predefined_variables)
|
|
variables.concat(pipeline_variables_builder.predefined_variables)
|
|
variables.concat(job.runner.predefined_variables) if job.runnable? && job.runner
|
|
variables.concat(kubernetes_variables(environment: environment, job: job))
|
|
variables.concat(job.yaml_variables)
|
|
variables.concat(user_variables(job.user))
|
|
variables.concat(job.dependency_variables) if dependencies
|
|
variables.concat(secret_instance_variables)
|
|
variables.concat(secret_group_variables(environment: environment))
|
|
variables.concat(secret_project_variables(environment: environment))
|
|
variables.concat(pipeline.variables)
|
|
variables.concat(pipeline_schedule_variables)
|
|
variables.concat(release_variables)
|
|
end
|
|
end
|
|
|
|
def config_variables
|
|
Gitlab::Ci::Variables::Collection.new.tap do |variables|
|
|
break variables unless project
|
|
|
|
variables.concat(project.predefined_variables)
|
|
variables.concat(pipeline_variables_builder.predefined_variables)
|
|
variables.concat(secret_instance_variables)
|
|
variables.concat(secret_group_variables(environment: nil))
|
|
variables.concat(secret_project_variables(environment: nil))
|
|
variables.concat(pipeline.variables)
|
|
variables.concat(pipeline_schedule_variables)
|
|
end
|
|
end
|
|
|
|
def kubernetes_variables(environment:, job:)
|
|
::Gitlab::Ci::Variables::Collection.new.tap do |collection|
|
|
# NOTE: deployment_variables will be removed as part of cleanup for
|
|
# https://gitlab.com/groups/gitlab-org/configure/-/epics/8
|
|
# Until then, we need to make both the old and the new KUBECONFIG contexts available
|
|
collection.concat(deployment_variables(environment: environment, job: job))
|
|
template = ::Ci::GenerateKubeconfigService.new(pipeline, token: job.try(:token), environment: environment).execute
|
|
kubeconfig_yaml = collection['KUBECONFIG']&.value
|
|
template.merge_yaml(kubeconfig_yaml) if kubeconfig_yaml.present?
|
|
|
|
if template.valid?
|
|
collection.append(key: 'KUBECONFIG', value: template.to_yaml, public: false, file: true)
|
|
end
|
|
end
|
|
end
|
|
|
|
def deployment_variables(environment:, job:)
|
|
return [] unless environment
|
|
|
|
project.deployment_variables(
|
|
environment: environment,
|
|
kubernetes_namespace: job.expanded_kubernetes_namespace
|
|
)
|
|
end
|
|
|
|
def user_variables(user)
|
|
Gitlab::Ci::Variables::Collection.new.tap do |variables|
|
|
break variables if user.blank?
|
|
|
|
variables.append(key: 'GITLAB_USER_ID', value: user.id.to_s)
|
|
variables.append(key: 'GITLAB_USER_EMAIL', value: user.email)
|
|
variables.append(key: 'GITLAB_USER_LOGIN', value: user.username)
|
|
variables.append(key: 'GITLAB_USER_NAME', value: user.name)
|
|
end
|
|
end
|
|
|
|
def secret_instance_variables
|
|
strong_memoize(:secret_instance_variables) do
|
|
instance_variables_builder
|
|
.secret_variables(protected_ref: protected_ref?)
|
|
end
|
|
end
|
|
|
|
def secret_group_variables(environment:)
|
|
strong_memoize_with(:secret_group_variables, environment) do
|
|
group_variables_builder
|
|
.secret_variables(
|
|
environment: environment,
|
|
protected_ref: protected_ref?)
|
|
end
|
|
end
|
|
|
|
def secret_project_variables(environment:)
|
|
strong_memoize_with(:secret_project_variables, environment) do
|
|
project_variables_builder
|
|
.secret_variables(
|
|
environment: environment,
|
|
protected_ref: protected_ref?)
|
|
end
|
|
end
|
|
|
|
def release_variables
|
|
strong_memoize(:release_variables) do
|
|
release_variables_builder.variables
|
|
end
|
|
end
|
|
|
|
private
|
|
|
|
attr_reader :pipeline
|
|
attr_reader :pipeline_variables_builder
|
|
attr_reader :instance_variables_builder
|
|
attr_reader :project_variables_builder
|
|
attr_reader :group_variables_builder
|
|
attr_reader :release_variables_builder
|
|
|
|
delegate :project, to: :pipeline
|
|
|
|
def predefined_variables(job)
|
|
Gitlab::Ci::Variables::Collection.new.tap do |variables|
|
|
variables.append(key: 'CI_JOB_NAME', value: job.name)
|
|
variables.append(key: 'CI_JOB_NAME_SLUG', value: job_name_slug(job))
|
|
variables.append(key: 'CI_JOB_STAGE', value: job.stage_name)
|
|
variables.append(key: 'CI_JOB_MANUAL', value: 'true') if job.action?
|
|
variables.append(key: 'CI_PIPELINE_TRIGGERED', value: 'true') if job.trigger_request
|
|
|
|
variables.append(key: 'CI_NODE_INDEX', value: job.options[:instance].to_s) if job.options&.include?(:instance)
|
|
variables.append(key: 'CI_NODE_TOTAL', value: ci_node_total_value(job).to_s)
|
|
|
|
# Set environment name here so we can access it when evaluating the job's rules
|
|
variables.append(key: 'CI_ENVIRONMENT_NAME', value: job.environment) if job.environment
|
|
|
|
# legacy variables
|
|
variables.append(key: 'CI_BUILD_NAME', value: job.name)
|
|
variables.append(key: 'CI_BUILD_STAGE', value: job.stage_name)
|
|
variables.append(key: 'CI_BUILD_TRIGGERED', value: 'true') if job.trigger_request
|
|
variables.append(key: 'CI_BUILD_MANUAL', value: 'true') if job.action?
|
|
end
|
|
end
|
|
|
|
def pipeline_schedule_variables
|
|
strong_memoize(:pipeline_schedule_variables) do
|
|
variables = if pipeline.pipeline_schedule
|
|
pipeline.pipeline_schedule.job_variables
|
|
else
|
|
[]
|
|
end
|
|
|
|
Gitlab::Ci::Variables::Collection.new(variables)
|
|
end
|
|
end
|
|
|
|
def job_name_slug(job)
|
|
job.name && Gitlab::Utils.slugify(job.name)
|
|
end
|
|
|
|
def ci_node_total_value(job)
|
|
parallel = job.options&.dig(:parallel)
|
|
parallel = parallel.dig(:total) if parallel.is_a?(Hash)
|
|
parallel || 1
|
|
end
|
|
|
|
def protected_ref?
|
|
strong_memoize(:protected_ref) do
|
|
project.protected_for?(pipeline.jobs_git_ref)
|
|
end
|
|
end
|
|
|
|
def release
|
|
return unless @pipeline.tag?
|
|
|
|
project.releases.find_by_tag(@pipeline.ref)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|