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
diff options
context:
space:
mode:
-rw-r--r--app/controllers/projects/prometheus/metrics_controller.rb2
-rw-r--r--app/models/ci/build.rb8
-rw-r--r--app/models/ci/pipeline.rb2
-rw-r--r--app/models/ci/pipeline_config.rb14
-rw-r--r--app/models/environment.rb2
-rw-r--r--app/serializers/build_artifact_entity.rb2
-rw-r--r--app/serializers/build_details_entity.rb2
-rw-r--r--app/services/prometheus/adapter_service.rb15
-rw-r--r--changelogs/unreleased/118640_add_gitlab_version_and_revision_to_export.yml5
-rw-r--r--changelogs/unreleased/38242-persisting-pipeline-config_content.yml5
-rw-r--r--changelogs/unreleased/eb-no-keep-report-artifacts.yml5
-rw-r--r--db/migrate/20191213143656_create_ci_pipelines_config.rb14
-rw-r--r--db/schema.rb6
-rw-r--r--doc/integration/elasticsearch.md9
-rw-r--r--lib/gitlab/ci/pipeline/chain/config/content.rb13
-rw-r--r--lib/gitlab/import_export.rb8
-rw-r--r--lib/gitlab/import_export/group_tree_saver.rb2
-rw-r--r--lib/gitlab/import_export/version_saver.rb10
-rw-r--r--lib/gitlab/kubernetes/kube_client.rb8
-rw-r--r--spec/lib/gitlab/ci/pipeline/chain/config/content_spec.rb95
-rw-r--r--spec/lib/gitlab/import_export/all_models.yml1
-rw-r--r--spec/lib/gitlab/kubernetes/kube_client_spec.rb37
-rw-r--r--spec/models/ci/build_spec.rb18
-rw-r--r--spec/models/ci/pipeline_config_spec.rb10
-rw-r--r--spec/models/ci/pipeline_spec.rb1
-rw-r--r--spec/serializers/build_artifact_entity_spec.rb2
-rw-r--r--spec/serializers/build_details_entity_spec.rb22
-rw-r--r--spec/services/prometheus/adapter_service_spec.rb7
-rw-r--r--spec/support/helpers/kubernetes_helpers.rb127
29 files changed, 342 insertions, 110 deletions
diff --git a/app/controllers/projects/prometheus/metrics_controller.rb b/app/controllers/projects/prometheus/metrics_controller.rb
index 267dca74f96..f212ae52ecc 100644
--- a/app/controllers/projects/prometheus/metrics_controller.rb
+++ b/app/controllers/projects/prometheus/metrics_controller.rb
@@ -23,7 +23,7 @@ module Projects
private
def prometheus_adapter
- @prometheus_adapter ||= ::Prometheus::AdapterService.new(project).prometheus_adapter
+ @prometheus_adapter ||= ::Prometheus::AdapterService.new(project, project.deployment_platform&.cluster).prometheus_adapter
end
def require_prometheus_metrics!
diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb
index fbf76f2c36a..f0930705a3f 100644
--- a/app/models/ci/build.rb
+++ b/app/models/ci/build.rb
@@ -719,8 +719,8 @@ module Ci
end
end
- def has_expiring_archive_artifacts?
- has_expiring_artifacts? && artifacts_file&.exists?
+ def has_expiring_artifacts?
+ artifacts_expire_at.present? && artifacts_expire_at > Time.now
end
def keep_artifacts!
@@ -935,10 +935,6 @@ module Ci
value.with_indifferent_access
end
end
-
- def has_expiring_artifacts?
- artifacts_expire_at.present? && artifacts_expire_at > Time.now
- end
end
end
diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb
index 29ec41ef1a1..42a40e06240 100644
--- a/app/models/ci/pipeline.rb
+++ b/app/models/ci/pipeline.rb
@@ -62,6 +62,8 @@ module Ci
has_one :triggered_by_pipeline, through: :source_pipeline, source: :source_pipeline
has_one :source_job, through: :source_pipeline, source: :source_job
+ has_one :pipeline_config, class_name: 'Ci::PipelineConfig', inverse_of: :pipeline
+
accepts_nested_attributes_for :variables, reject_if: :persisted?
delegate :id, to: :project, prefix: true
diff --git a/app/models/ci/pipeline_config.rb b/app/models/ci/pipeline_config.rb
new file mode 100644
index 00000000000..d5a8da2bc1e
--- /dev/null
+++ b/app/models/ci/pipeline_config.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+module Ci
+ class PipelineConfig < ApplicationRecord
+ extend Gitlab::Ci::Model
+
+ self.table_name = 'ci_pipelines_config'
+ self.primary_key = :pipeline_id
+
+ belongs_to :pipeline, class_name: "Ci::Pipeline", inverse_of: :pipeline_config
+ validates :pipeline, presence: true
+ validates :content, presence: true
+ end
+end
diff --git a/app/models/environment.rb b/app/models/environment.rb
index 84a72fee77b..7ef38ab4cf4 100644
--- a/app/models/environment.rb
+++ b/app/models/environment.rb
@@ -223,7 +223,7 @@ class Environment < ApplicationRecord
# rubocop: disable CodeReuse/ServiceClass
def prometheus_adapter
- @prometheus_adapter ||= Prometheus::AdapterService.new(project, deployment_platform).prometheus_adapter
+ @prometheus_adapter ||= Prometheus::AdapterService.new(project, deployment_platform&.cluster).prometheus_adapter
end
# rubocop: enable CodeReuse/ServiceClass
diff --git a/app/serializers/build_artifact_entity.rb b/app/serializers/build_artifact_entity.rb
index c173c155edf..414f436e76e 100644
--- a/app/serializers/build_artifact_entity.rb
+++ b/app/serializers/build_artifact_entity.rb
@@ -14,7 +14,7 @@ class BuildArtifactEntity < Grape::Entity
download_project_job_artifacts_path(project, job)
end
- expose :keep_path, if: -> (*) { job.has_expiring_archive_artifacts? } do |job|
+ expose :keep_path, if: -> (*) { job.has_expiring_artifacts? } do |job|
keep_project_job_artifacts_path(project, job)
end
diff --git a/app/serializers/build_details_entity.rb b/app/serializers/build_details_entity.rb
index 0ef71ff8af5..480a8cab6ff 100644
--- a/app/serializers/build_details_entity.rb
+++ b/app/serializers/build_details_entity.rb
@@ -31,7 +31,7 @@ class BuildDetailsEntity < JobEntity
browse_project_job_artifacts_path(project, build)
end
- expose :keep_path, if: -> (*) { build.has_expiring_archive_artifacts? && can?(current_user, :update_build, build) } do |build|
+ expose :keep_path, if: -> (*) { build.has_expiring_artifacts? && can?(current_user, :update_build, build) } do |build|
keep_project_job_artifacts_path(project, build)
end
diff --git a/app/services/prometheus/adapter_service.rb b/app/services/prometheus/adapter_service.rb
index 399f4c35d66..5e8357a83f6 100644
--- a/app/services/prometheus/adapter_service.rb
+++ b/app/services/prometheus/adapter_service.rb
@@ -2,18 +2,13 @@
module Prometheus
class AdapterService
- def initialize(project, deployment_platform = nil)
- @project = project
+ attr_reader :project, :cluster
- @deployment_platform = if deployment_platform
- deployment_platform
- else
- project.deployment_platform
- end
+ def initialize(project, cluster)
+ @project = project
+ @cluster = cluster
end
- attr_reader :deployment_platform, :project
-
def prometheus_adapter
@prometheus_adapter ||= if service_prometheus_adapter.can_query?
service_prometheus_adapter
@@ -27,7 +22,7 @@ module Prometheus
end
def cluster_prometheus_adapter
- application = deployment_platform&.cluster&.application_prometheus
+ application = cluster&.application_prometheus
application if application&.available?
end
diff --git a/changelogs/unreleased/118640_add_gitlab_version_and_revision_to_export.yml b/changelogs/unreleased/118640_add_gitlab_version_and_revision_to_export.yml
new file mode 100644
index 00000000000..416f241a726
--- /dev/null
+++ b/changelogs/unreleased/118640_add_gitlab_version_and_revision_to_export.yml
@@ -0,0 +1,5 @@
+---
+title: Add Gitlab version and revision to export
+merge_request: 22108
+author:
+type: added
diff --git a/changelogs/unreleased/38242-persisting-pipeline-config_content.yml b/changelogs/unreleased/38242-persisting-pipeline-config_content.yml
new file mode 100644
index 00000000000..02c391186f9
--- /dev/null
+++ b/changelogs/unreleased/38242-persisting-pipeline-config_content.yml
@@ -0,0 +1,5 @@
+---
+title: Implement saving config content for pipelines in a new table 'ci_pipelines_config'
+merge_request: 21827
+author:
+type: other
diff --git a/changelogs/unreleased/eb-no-keep-report-artifacts.yml b/changelogs/unreleased/eb-no-keep-report-artifacts.yml
deleted file mode 100644
index c80fbd2c221..00000000000
--- a/changelogs/unreleased/eb-no-keep-report-artifacts.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Remove keep button for non archive artifacts
-merge_request: 21553
-author:
-type: fixed
diff --git a/db/migrate/20191213143656_create_ci_pipelines_config.rb b/db/migrate/20191213143656_create_ci_pipelines_config.rb
new file mode 100644
index 00000000000..92636f35d01
--- /dev/null
+++ b/db/migrate/20191213143656_create_ci_pipelines_config.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+class CreateCiPipelinesConfig < ActiveRecord::Migration[5.2]
+ DOWNTIME = false
+
+ def change
+ create_table :ci_pipelines_config, id: false do |t|
+ t.references :pipeline,
+ primary_key: true,
+ foreign_key: { to_table: :ci_pipelines, on_delete: :cascade }
+ t.text :content, null: false
+ end
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 0f709482884..219ac8c5263 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -876,6 +876,11 @@ ActiveRecord::Schema.define(version: 2019_12_18_225624) do
t.index ["user_id"], name: "index_ci_pipelines_on_user_id"
end
+ create_table "ci_pipelines_config", primary_key: "pipeline_id", force: :cascade do |t|
+ t.text "content", null: false
+ t.index ["pipeline_id"], name: "index_ci_pipelines_config_on_pipeline_id"
+ end
+
create_table "ci_resource_groups", force: :cascade do |t|
t.datetime_with_timezone "created_at", null: false
t.datetime_with_timezone "updated_at", null: false
@@ -4438,6 +4443,7 @@ ActiveRecord::Schema.define(version: 2019_12_18_225624) do
add_foreign_key "ci_pipelines", "external_pull_requests", name: "fk_190998ef09", on_delete: :nullify
add_foreign_key "ci_pipelines", "merge_requests", name: "fk_a23be95014", on_delete: :cascade
add_foreign_key "ci_pipelines", "projects", name: "fk_86635dbd80", on_delete: :cascade
+ add_foreign_key "ci_pipelines_config", "ci_pipelines", column: "pipeline_id", on_delete: :cascade
add_foreign_key "ci_resource_groups", "projects", name: "fk_774722d144", on_delete: :cascade
add_foreign_key "ci_resources", "ci_builds", column: "build_id", name: "fk_e169a8e3d5", on_delete: :nullify
add_foreign_key "ci_resources", "ci_resource_groups", column: "resource_group_id", on_delete: :cascade
diff --git a/doc/integration/elasticsearch.md b/doc/integration/elasticsearch.md
index 7d07e8f6944..292cddd284b 100644
--- a/doc/integration/elasticsearch.md
+++ b/doc/integration/elasticsearch.md
@@ -200,8 +200,7 @@ To backfill existing data, you can use one of the methods below to index it in b
To index via the admin area:
-1. Navigate to the **Admin Area** (wrench icon), then **Settings > Integrations** and expand the **Elasticsearch** section.
-1. [Enable **Elasticsearch indexing** and configure your host and port](#enabling-elasticsearch).
+1. [Configure your Elasticsearch host and port](#enabling-elasticsearch).
1. Create empty indexes using one of the following commands:
```sh
@@ -212,7 +211,8 @@ To index via the admin area:
bundle exec rake gitlab:elastic:create_empty_index RAILS_ENV=production
```
-1. Click **Index all projects**.
+1. [Enable **Elasticsearch indexing**](#enabling-elasticsearch).
+1. Click **Index all projects** in **Admin Area > Settings > Integrations > Elasticsearch**.
1. Click **Check progress** in the confirmation message to see the status of the background jobs.
1. Personal snippets need to be indexed manually by running one of these commands:
@@ -255,7 +255,7 @@ Performing asynchronous indexing will generate a lot of Sidekiq jobs.
Make sure to prepare for this task by either [Horizontally Scaling](../administration/high_availability/README.md#basic-scaling)
or creating [extra Sidekiq processes](../administration/operations/extra_sidekiq_processes.md)
-1. [Enable **Elasticsearch indexing** and configure your host and port](#enabling-elasticsearch).
+1. [Configure your Elasticsearch host and port](#enabling-elasticsearch).
1. Create empty indexes using one of the following commands:
```sh
@@ -266,6 +266,7 @@ or creating [extra Sidekiq processes](../administration/operations/extra_sidekiq
bundle exec rake gitlab:elastic:create_empty_index RAILS_ENV=production
```
+1. [Enable **Elasticsearch indexing**](#enabling-elasticsearch).
1. Indexing large Git repositories can take a while. To speed up the process, you
can temporarily disable auto-refreshing and replicating. In our experience, you can expect a 20%
decrease in indexing time. We'll enable them when indexing is done. This step is optional!
diff --git a/lib/gitlab/ci/pipeline/chain/config/content.rb b/lib/gitlab/ci/pipeline/chain/config/content.rb
index d4b7444005e..f9fffbcb517 100644
--- a/lib/gitlab/ci/pipeline/chain/config/content.rb
+++ b/lib/gitlab/ci/pipeline/chain/config/content.rb
@@ -24,8 +24,7 @@ module Gitlab
def perform!
if config = find_config
- # TODO: we should persist config_content
- # @pipeline.config_content = config.content
+ @pipeline.build_pipeline_config(content: config.content) if ci_root_config_content_enabled?
@command.config_content = config.content
@pipeline.config_source = config.source
else
@@ -49,11 +48,11 @@ module Gitlab
end
def sources
- if Feature.enabled?(:ci_root_config_content, @command.project, default_enabled: true)
- SOURCES
- else
- LEGACY_SOURCES
- end
+ ci_root_config_content_enabled? ? SOURCES : LEGACY_SOURCES
+ end
+
+ def ci_root_config_content_enabled?
+ Feature.enabled?(:ci_root_config_content, @command.project, default_enabled: true)
end
end
end
diff --git a/lib/gitlab/import_export.rb b/lib/gitlab/import_export.rb
index 516e7f54a6e..8ce6549c0c7 100644
--- a/lib/gitlab/import_export.rb
+++ b/lib/gitlab/import_export.rb
@@ -50,6 +50,14 @@ module Gitlab
'VERSION'
end
+ def gitlab_version_filename
+ 'GITLAB_VERSION'
+ end
+
+ def gitlab_revision_filename
+ 'GITLAB_REVISION'
+ end
+
def export_filename(exportable:)
basename = "#{Time.now.strftime('%Y-%m-%d_%H-%M-%3N')}_#{exportable.full_path.tr('/', '_')}"
diff --git a/lib/gitlab/import_export/group_tree_saver.rb b/lib/gitlab/import_export/group_tree_saver.rb
index 8d2fb881cc0..2effcd01e30 100644
--- a/lib/gitlab/import_export/group_tree_saver.rb
+++ b/lib/gitlab/import_export/group_tree_saver.rb
@@ -3,7 +3,7 @@
module Gitlab
module ImportExport
class GroupTreeSaver
- attr_reader :full_path
+ attr_reader :full_path, :shared
def initialize(group:, current_user:, shared:, params: {})
@params = params
diff --git a/lib/gitlab/import_export/version_saver.rb b/lib/gitlab/import_export/version_saver.rb
index 8230c0f1e77..dab8bbf539d 100644
--- a/lib/gitlab/import_export/version_saver.rb
+++ b/lib/gitlab/import_export/version_saver.rb
@@ -13,6 +13,8 @@ module Gitlab
mkdir_p(@shared.export_path)
File.write(version_file, Gitlab::ImportExport.version, mode: 'w')
+ File.write(gitlab_version_file, Gitlab::VERSION, mode: 'w')
+ File.write(gitlab_revision_file, Gitlab.revision, mode: 'w')
rescue => e
@shared.error(e)
false
@@ -20,6 +22,14 @@ module Gitlab
private
+ def gitlab_version_file
+ File.join(@shared.export_path, Gitlab::ImportExport.gitlab_version_filename)
+ end
+
+ def gitlab_revision_file
+ File.join(@shared.export_path, Gitlab::ImportExport.gitlab_revision_filename)
+ end
+
def version_file
File.join(@shared.export_path, Gitlab::ImportExport.version_filename)
end
diff --git a/lib/gitlab/kubernetes/kube_client.rb b/lib/gitlab/kubernetes/kube_client.rb
index b23ca095414..21d5c9b0eee 100644
--- a/lib/gitlab/kubernetes/kube_client.rb
+++ b/lib/gitlab/kubernetes/kube_client.rb
@@ -17,6 +17,7 @@ module Gitlab
core: { group: 'api', version: 'v1' },
rbac: { group: 'apis/rbac.authorization.k8s.io', version: 'v1' },
extensions: { group: 'apis/extensions', version: 'v1beta1' },
+ istio: { group: 'apis/networking.istio.io', version: 'v1alpha3' },
knative: { group: 'apis/serving.knative.dev', version: 'v1alpha1' }
}.freeze
@@ -91,6 +92,13 @@ module Gitlab
:watch_pod_log,
to: :core_client
+ # Gateway methods delegate to the apis/networking.istio.io api
+ # group client
+ delegate :create_gateway,
+ :get_gateway,
+ :update_gateway,
+ to: :istio_client
+
attr_reader :api_prefix, :kubeclient_options
# We disable redirects through 'http_max_redirects: 0',
diff --git a/spec/lib/gitlab/ci/pipeline/chain/config/content_spec.rb b/spec/lib/gitlab/ci/pipeline/chain/config/content_spec.rb
index f84f10bdc46..aaea044595f 100644
--- a/spec/lib/gitlab/ci/pipeline/chain/config/content_spec.rb
+++ b/spec/lib/gitlab/ci/pipeline/chain/config/content_spec.rb
@@ -29,6 +29,7 @@ describe Gitlab::Ci::Pipeline::Chain::Config::Content do
subject.perform!
expect(pipeline.config_source).to eq 'repository_source'
+ expect(pipeline.pipeline_config).to be_nil
expect(command.config_content).to eq('the-content')
end
end
@@ -40,6 +41,7 @@ describe Gitlab::Ci::Pipeline::Chain::Config::Content do
subject.perform!
expect(pipeline.config_source).to eq 'auto_devops_source'
+ expect(pipeline.pipeline_config).to be_nil
template = Gitlab::Template::GitlabCiYmlTemplate.find('Beta/Auto-DevOps')
expect(command.config_content).to eq(template.content)
end
@@ -52,6 +54,7 @@ describe Gitlab::Ci::Pipeline::Chain::Config::Content do
subject.perform!
expect(pipeline.config_source).to eq 'auto_devops_source'
+ expect(pipeline.pipeline_config).to be_nil
template = Gitlab::Template::GitlabCiYmlTemplate.find('Beta/Auto-DevOps')
expect(command.config_content).to eq(template.content)
end
@@ -71,6 +74,7 @@ describe Gitlab::Ci::Pipeline::Chain::Config::Content do
subject.perform!
expect(pipeline.config_source).to eq 'repository_source'
+ expect(pipeline.pipeline_config).to be_nil
expect(command.config_content).to eq('the-content')
end
end
@@ -91,6 +95,7 @@ describe Gitlab::Ci::Pipeline::Chain::Config::Content do
subject.perform!
expect(pipeline.config_source).to eq 'auto_devops_source'
+ expect(pipeline.pipeline_config).to be_nil
template = Gitlab::Template::GitlabCiYmlTemplate.find('Beta/Auto-DevOps')
expect(command.config_content).to eq(template.content)
end
@@ -105,6 +110,7 @@ describe Gitlab::Ci::Pipeline::Chain::Config::Content do
subject.perform!
expect(pipeline.config_source).to eq 'auto_devops_source'
+ expect(pipeline.pipeline_config).to be_nil
template = Gitlab::Template::GitlabCiYmlTemplate.find('Auto-DevOps')
expect(command.config_content).to eq(template.content)
end
@@ -122,6 +128,7 @@ describe Gitlab::Ci::Pipeline::Chain::Config::Content do
subject.perform!
expect(pipeline.config_source).to eq('unknown_source')
+ expect(pipeline.pipeline_config).to be_nil
expect(command.config_content).to be_nil
expect(pipeline.errors.full_messages).to include('Missing CI config file')
end
@@ -130,6 +137,13 @@ describe Gitlab::Ci::Pipeline::Chain::Config::Content do
context 'when config is defined in a custom path in the repository' do
let(:ci_config_path) { 'path/to/config.yml' }
+ let(:config_content_result) do
+ <<~EOY
+ ---
+ include:
+ - local: #{ci_config_path}
+ EOY
+ end
before do
expect(project.repository)
@@ -142,47 +156,59 @@ describe Gitlab::Ci::Pipeline::Chain::Config::Content do
subject.perform!
expect(pipeline.config_source).to eq 'repository_source'
- expect(command.config_content).to eq(<<~EOY)
- ---
- include:
- - local: #{ci_config_path}
- EOY
+ expect(pipeline.pipeline_config.content).to eq(config_content_result)
+ expect(command.config_content).to eq(config_content_result)
end
end
context 'when config is defined remotely' do
let(:ci_config_path) { 'http://example.com/path/to/ci/config.yml' }
+ let(:config_content_result) do
+ <<~EOY
+ ---
+ include:
+ - remote: #{ci_config_path}
+ EOY
+ end
it 'builds root config including the remote config' do
subject.perform!
expect(pipeline.config_source).to eq 'remote_source'
- expect(command.config_content).to eq(<<~EOY)
- ---
- include:
- - remote: #{ci_config_path}
- EOY
+ expect(pipeline.pipeline_config.content).to eq(config_content_result)
+ expect(command.config_content).to eq(config_content_result)
end
end
context 'when config is defined in a separate repository' do
let(:ci_config_path) { 'path/to/.gitlab-ci.yml@another-group/another-repo' }
-
- it 'builds root config including the path to another repository' do
- subject.perform!
-
- expect(pipeline.config_source).to eq 'external_project_source'
- expect(command.config_content).to eq(<<~EOY)
+ let(:config_content_result) do
+ <<~EOY
---
include:
- project: another-group/another-repo
file: path/to/.gitlab-ci.yml
EOY
end
+
+ it 'builds root config including the path to another repository' do
+ subject.perform!
+
+ expect(pipeline.config_source).to eq 'external_project_source'
+ expect(pipeline.pipeline_config.content).to eq(config_content_result)
+ expect(command.config_content).to eq(config_content_result)
+ end
end
context 'when config is defined in the default .gitlab-ci.yml' do
let(:ci_config_path) { nil }
+ let(:config_content_result) do
+ <<~EOY
+ ---
+ include:
+ - local: ".gitlab-ci.yml"
+ EOY
+ end
before do
expect(project.repository)
@@ -195,16 +221,20 @@ describe Gitlab::Ci::Pipeline::Chain::Config::Content do
subject.perform!
expect(pipeline.config_source).to eq 'repository_source'
- expect(command.config_content).to eq(<<~EOY)
- ---
- include:
- - local: ".gitlab-ci.yml"
- EOY
+ expect(pipeline.pipeline_config.content).to eq(config_content_result)
+ expect(command.config_content).to eq(config_content_result)
end
end
context 'when config is the Auto-Devops template' do
let(:ci_config_path) { nil }
+ let(:config_content_result) do
+ <<~EOY
+ ---
+ include:
+ - template: Beta/Auto-DevOps.gitlab-ci.yml
+ EOY
+ end
before do
expect(project).to receive(:auto_devops_enabled?).and_return(true)
@@ -219,11 +249,8 @@ describe Gitlab::Ci::Pipeline::Chain::Config::Content do
subject.perform!
expect(pipeline.config_source).to eq 'auto_devops_source'
- expect(command.config_content).to eq(<<~EOY)
- ---
- include:
- - template: Beta/Auto-DevOps.gitlab-ci.yml
- EOY
+ expect(pipeline.pipeline_config.content).to eq(config_content_result)
+ expect(command.config_content).to eq(config_content_result)
end
end
@@ -232,16 +259,21 @@ describe Gitlab::Ci::Pipeline::Chain::Config::Content do
stub_feature_flags(auto_devops_beta: false)
end
- it 'builds root config including the auto-devops template' do
- subject.perform!
-
- expect(pipeline.config_source).to eq 'auto_devops_source'
- expect(command.config_content).to eq(<<~EOY)
+ let(:config_content_result) do
+ <<~EOY
---
include:
- template: Auto-DevOps.gitlab-ci.yml
EOY
end
+
+ it 'builds root config including the auto-devops template' do
+ subject.perform!
+
+ expect(pipeline.config_source).to eq 'auto_devops_source'
+ expect(pipeline.pipeline_config.content).to eq(config_content_result)
+ expect(command.config_content).to eq(config_content_result)
+ end
end
end
@@ -256,6 +288,7 @@ describe Gitlab::Ci::Pipeline::Chain::Config::Content do
subject.perform!
expect(pipeline.config_source).to eq('unknown_source')
+ expect(pipeline.pipeline_config).to be_nil
expect(command.config_content).to be_nil
expect(pipeline.errors.full_messages).to include('Missing CI config file')
end
diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml
index 8f0f09bc0be..a625d2f6cce 100644
--- a/spec/lib/gitlab/import_export/all_models.yml
+++ b/spec/lib/gitlab/import_export/all_models.yml
@@ -190,6 +190,7 @@ ci_pipelines:
- job_artifacts
- vulnerabilities_occurrence_pipelines
- vulnerability_findings
+- pipeline_config
pipeline_variables:
- pipeline
stages:
diff --git a/spec/lib/gitlab/kubernetes/kube_client_spec.rb b/spec/lib/gitlab/kubernetes/kube_client_spec.rb
index 59e81d89a50..e08981a3415 100644
--- a/spec/lib/gitlab/kubernetes/kube_client_spec.rb
+++ b/spec/lib/gitlab/kubernetes/kube_client_spec.rb
@@ -136,6 +136,20 @@ describe Gitlab::Kubernetes::KubeClient do
end
end
+ describe '#istio_client' do
+ subject { client.istio_client }
+
+ it_behaves_like 'a Kubeclient'
+
+ it 'has the Istio API group endpoint' do
+ expect(subject.api_endpoint.to_s).to match(%r{\/apis\/networking.istio.io\Z})
+ end
+
+ it 'has the api_version' do
+ expect(subject.instance_variable_get(:@api_version)).to eq('v1alpha3')
+ end
+ end
+
describe '#knative_client' do
subject { client.knative_client }
@@ -233,6 +247,29 @@ describe Gitlab::Kubernetes::KubeClient do
end
end
+ describe 'istio API group' do
+ let(:istio_client) { client.istio_client }
+
+ [
+ :create_gateway,
+ :get_gateway,
+ :update_gateway
+ ].each do |method|
+ describe "##{method}" do
+ include_examples 'redirection not allowed', method
+ include_examples 'dns rebinding not allowed', method
+
+ it 'delegates to the istio client' do
+ expect(client).to delegate_method(method).to(:istio_client)
+ end
+
+ it 'responds to the method' do
+ expect(client).to respond_to method
+ end
+ end
+ end
+ end
+
describe 'non-entity methods' do
it 'does not proxy for non-entity methods' do
expect(client).not_to respond_to :proxy_url
diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb
index ee8e9805c49..f9c17f732b6 100644
--- a/spec/models/ci/build_spec.rb
+++ b/spec/models/ci/build_spec.rb
@@ -2248,24 +2248,14 @@ describe Ci::Build do
end
end
- describe '#has_expiring_archive_artifacts?' do
+ describe '#has_expiring_artifacts?' do
context 'when artifacts have expiration date set' do
before do
build.update(artifacts_expire_at: 1.day.from_now)
end
- context 'and job artifacts file exists' do
- let!(:archive) { create(:ci_job_artifact, :archive, job: build) }
-
- it 'has expiring artifacts' do
- expect(build).to have_expiring_archive_artifacts
- end
- end
-
- context 'and job artifacts file does not exist' do
- it 'does not have expiring artifacts' do
- expect(build).not_to have_expiring_archive_artifacts
- end
+ it 'has expiring artifacts' do
+ expect(build).to have_expiring_artifacts
end
end
@@ -2275,7 +2265,7 @@ describe Ci::Build do
end
it 'does not have expiring artifacts' do
- expect(build).not_to have_expiring_archive_artifacts
+ expect(build).not_to have_expiring_artifacts
end
end
end
diff --git a/spec/models/ci/pipeline_config_spec.rb b/spec/models/ci/pipeline_config_spec.rb
new file mode 100644
index 00000000000..25f514ee5ab
--- /dev/null
+++ b/spec/models/ci/pipeline_config_spec.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Ci::PipelineConfig, type: :model do
+ it { is_expected.to belong_to(:pipeline) }
+
+ it { is_expected.to validate_presence_of(:pipeline) }
+ it { is_expected.to validate_presence_of(:content) }
+end
diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb
index 3f9e882ea52..286d2ac4fe6 100644
--- a/spec/models/ci/pipeline_spec.rb
+++ b/spec/models/ci/pipeline_spec.rb
@@ -35,6 +35,7 @@ describe Ci::Pipeline, :mailer do
it { is_expected.to have_one(:source_pipeline) }
it { is_expected.to have_one(:triggered_by_pipeline) }
it { is_expected.to have_one(:source_job) }
+ it { is_expected.to have_one(:pipeline_config) }
it { is_expected.to validate_presence_of(:sha) }
it { is_expected.to validate_presence_of(:status) }
diff --git a/spec/serializers/build_artifact_entity_spec.rb b/spec/serializers/build_artifact_entity_spec.rb
index 5f1d5093e0a..09fe094fff1 100644
--- a/spec/serializers/build_artifact_entity_spec.rb
+++ b/spec/serializers/build_artifact_entity_spec.rb
@@ -4,8 +4,6 @@ require 'spec_helper'
describe BuildArtifactEntity do
let(:job) { create(:ci_build, name: 'test:job', artifacts_expire_at: 1.hour.from_now) }
- let!(:archive) { create(:ci_job_artifact, :archive, job: job) }
- let!(:metadata) { create(:ci_job_artifact, :metadata, job: job) }
let(:entity) do
described_class.new(job, request: double)
diff --git a/spec/serializers/build_details_entity_spec.rb b/spec/serializers/build_details_entity_spec.rb
index 6fe9eaedfeb..91c5fd6bf2c 100644
--- a/spec/serializers/build_details_entity_spec.rb
+++ b/spec/serializers/build_details_entity_spec.rb
@@ -176,27 +176,5 @@ describe BuildDetailsEntity do
expect(subject[:reports].first[:file_type]).to eq('codequality')
end
end
-
- context 'when the build has no archive type artifacts' do
- let!(:report) { create(:ci_job_artifact, :codequality, job: build) }
-
- it 'does not expose any artifact actions path' do
- expect(subject[:artifact].keys).not_to include(:download_path, :browse_path, :keep_path)
- end
- end
-
- context 'when the build has archive type artifacts' do
- let!(:report) { create(:ci_job_artifact, :codequality, job: build) }
- let!(:archive) { create(:ci_job_artifact, :archive, job: build) }
- let!(:metadata) { create(:ci_job_artifact, :metadata, job: build) }
-
- before do
- build.update(artifacts_expire_at: 7.days.from_now)
- end
-
- it 'exposes artifact details' do
- expect(subject[:artifact].keys).to include(:download_path, :browse_path, :keep_path, :expire_at, :expired)
- end
- end
end
end
diff --git a/spec/services/prometheus/adapter_service_spec.rb b/spec/services/prometheus/adapter_service_spec.rb
index 52e035e1f70..3c075fc1581 100644
--- a/spec/services/prometheus/adapter_service_spec.rb
+++ b/spec/services/prometheus/adapter_service_spec.rb
@@ -3,13 +3,12 @@
require 'spec_helper'
describe Prometheus::AdapterService do
- let(:project) { create(:project) }
+ let_it_be(:project) { create(:project) }
+ let_it_be(:cluster, reload: true) { create(:cluster, :provided_by_user, environment_scope: '*', projects: [project]) }
- subject { described_class.new(project) }
+ subject { described_class.new(project, cluster) }
describe '#prometheus_adapter' do
- let(:cluster) { create(:cluster, :provided_by_user, environment_scope: '*', projects: [project]) }
-
context 'prometheus service can execute queries' do
let(:prometheus_service) { double(:prometheus_service, can_query?: true) }
diff --git a/spec/support/helpers/kubernetes_helpers.rb b/spec/support/helpers/kubernetes_helpers.rb
index b2145ca729f..2fabfb94928 100644
--- a/spec/support/helpers/kubernetes_helpers.rb
+++ b/spec/support/helpers/kubernetes_helpers.rb
@@ -33,6 +33,14 @@ module KubernetesHelpers
.to_return(kube_response(kube_v1_rbac_authorization_discovery_body))
end
+ def stub_kubeclient_discover_istio(api_url)
+ stub_kubeclient_discover_base(api_url)
+
+ WebMock
+ .stub_request(:get, api_url + '/apis/networking.istio.io/v1alpha3')
+ .to_return(kube_response(kube_istio_discovery_body))
+ end
+
def stub_kubeclient_discover(api_url)
stub_kubeclient_discover_base(api_url)
@@ -244,6 +252,16 @@ module KubernetesHelpers
.to_return(kube_response({}))
end
+ def stub_kubeclient_get_gateway(api_url, name, namespace: 'default')
+ WebMock.stub_request(:get, api_url + "/apis/networking.istio.io/v1alpha3/namespaces/#{namespace}/gateways/#{name}")
+ .to_return(kube_response(kube_istio_gateway_body(name, namespace)))
+ end
+
+ def stub_kubeclient_put_gateway(api_url, name, namespace: 'default')
+ WebMock.stub_request(:put, api_url + "/apis/networking.istio.io/v1alpha3/namespaces/#{namespace}/gateways/#{name}")
+ .to_return(kube_response({}))
+ end
+
def kube_v1_secret_body(**options)
{
"kind" => "SecretList",
@@ -311,6 +329,115 @@ module KubernetesHelpers
}
end
+ def kube_istio_discovery_body
+ {
+ "kind" => "APIResourceList",
+ "apiVersion" => "v1",
+ "groupVersion" => "networking.istio.io/v1alpha3",
+ "resources" => [
+ {
+ "name" => "gateways",
+ "singularName" => "gateway",
+ "namespaced" => true,
+ "kind" => "Gateway",
+ "verbs" => %w[delete deletecollection get list patch create update watch],
+ "shortNames" => %w[gw],
+ "categories" => %w[istio-io networking-istio-io]
+ },
+ {
+ "name" => "serviceentries",
+ "singularName" => "serviceentry",
+ "namespaced" => true,
+ "kind" => "ServiceEntry",
+ "verbs" => %w[delete deletecollection get list patch create update watch],
+ "shortNames" => %w[se],
+ "categories" => %w[istio-io networking-istio-io]
+ },
+ {
+ "name" => "destinationrules",
+ "singularName" => "destinationrule",
+ "namespaced" => true,
+ "kind" => "DestinationRule",
+ "verbs" => %w[delete deletecollection get list patch create update watch],
+ "shortNames" => %w[dr],
+ "categories" => %w[istio-io networking-istio-io]
+ },
+ {
+ "name" => "envoyfilters",
+ "singularName" => "envoyfilter",
+ "namespaced" => true,
+ "kind" => "EnvoyFilter",
+ "verbs" => %w[delete deletecollection get list patch create update watch],
+ "categories" => %w[istio-io networking-istio-io]
+ },
+ {
+ "name" => "sidecars",
+ "singularName" => "sidecar",
+ "namespaced" => true,
+ "kind" => "Sidecar",
+ "verbs" => %w[delete deletecollection get list patch create update watch],
+ "categories" => %w[istio-io networking-istio-io]
+ },
+ {
+ "name" => "virtualservices",
+ "singularName" => "virtualservice",
+ "namespaced" => true,
+ "kind" => "VirtualService",
+ "verbs" => %w[delete deletecollection get list patch create update watch],
+ "shortNames" => %w[vs],
+ "categories" => %w[istio-io networking-istio-io]
+ }
+ ]
+ }
+ end
+
+ def kube_istio_gateway_body(name, namespace)
+ {
+ "apiVersion" => "networking.istio.io/v1alpha3",
+ "kind" => "Gateway",
+ "metadata" => {
+ "generation" => 1,
+ "labels" => {
+ "networking.knative.dev/ingress-provider" => "istio",
+ "serving.knative.dev/release" => "v0.7.0"
+ },
+ "name" => name,
+ "namespace" => namespace,
+ "selfLink" => "/apis/networking.istio.io/v1alpha3/namespaces/#{namespace}/gateways/#{name}"
+ },
+ "spec" => {
+ "selector" => {
+ "istio" => "ingressgateway"
+ },
+ "servers" => [
+ {
+ "hosts" => [
+ "*"
+ ],
+ "port" => {
+ "name" => "http",
+ "number" => 80,
+ "protocol" => "HTTP"
+ }
+ },
+ {
+ "hosts" => [
+ "*"
+ ],
+ "port" => {
+ "name" => "https",
+ "number" => 443,
+ "protocol" => "HTTPS"
+ },
+ "tls" => {
+ "mode" => "PASSTHROUGH"
+ }
+ }
+ ]
+ }
+ }
+ end
+
def kube_v1alpha1_serving_knative_discovery_body
{
"kind" => "APIResourceList",