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

Merge branch 'add-clusters-to-deployment' into 'master'

Add clusters association to deployment

See merge request gitlab-org/gitlab-ce!29960
parents 5ad09f38 04af6132
......@@ -18,6 +18,7 @@ module Deployable
return unless environment.persisted?
create_deployment!(
cluster_id: environment.deployment_platform&.cluster_id,
project_id: environment.project_id,
environment: environment,
ref: ref,
......
......@@ -7,6 +7,7 @@ class Deployment < ApplicationRecord
belongs_to :project, required: true
belongs_to :environment, required: true
belongs_to :cluster, class_name: 'Clusters::Cluster', optional: true
belongs_to :user
belongs_to :deployable, polymorphic: true # rubocop:disable Cop/PolymorphicAssociations
......@@ -196,7 +197,22 @@ class Deployment < ApplicationRecord
private
def prometheus_adapter
environment.prometheus_adapter
service = project.find_or_initialize_service('prometheus')
if service.can_query?
service
else
cluster_prometheus
end
end
# TODO remove fallback case to deployment_platform_cluster.
# Otherwise we will continue to pay the performance penalty described in
# https://gitlab.com/gitlab-org/gitlab-ce/issues/63475
def cluster_prometheus
cluster_with_fallback = cluster || deployment_platform_cluster
cluster_with_fallback.application_prometheus if cluster_with_fallback&.application_prometheus_available?
end
def ref_path
......
---
title: Persist the cluster a deployment was deployed to
merge_request: 29960
author:
type: fixed
# frozen_string_literal: true
class AddClusterIdToDeployments < ActiveRecord::Migration[5.1]
DOWNTIME = false
def change
add_column :deployments, :cluster_id, :integer
end
end
# frozen_string_literal: true
class AddClusterIdIndexFkToDeployments < ActiveRecord::Migration[5.1]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
disable_ddl_transaction!
def up
add_concurrent_index :deployments, :cluster_id
add_concurrent_foreign_key :deployments, :clusters, column: :cluster_id, on_delete: :nullify
end
def down
remove_foreign_key :deployments, :clusters
remove_concurrent_index :deployments, :cluster_id
end
end
......@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20190625184066) do
ActiveRecord::Schema.define(version: 20190627051902) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
......@@ -1066,6 +1066,8 @@ ActiveRecord::Schema.define(version: 20190625184066) do
t.string "on_stop"
t.integer "status", limit: 2, null: false
t.datetime_with_timezone "finished_at"
t.integer "cluster_id"
t.index ["cluster_id"], name: "index_deployments_on_cluster_id", using: :btree
t.index ["created_at"], name: "index_deployments_on_created_at", using: :btree
t.index ["deployable_type", "deployable_id"], name: "index_deployments_on_deployable_type_and_deployable_id", using: :btree
t.index ["environment_id", "id"], name: "index_deployments_on_environment_id_and_id", using: :btree
......@@ -3659,6 +3661,7 @@ ActiveRecord::Schema.define(version: 20190625184066) do
add_foreign_key "dependency_proxy_blobs", "namespaces", column: "group_id", name: "fk_db58bbc5d7", on_delete: :cascade
add_foreign_key "dependency_proxy_group_settings", "namespaces", column: "group_id", name: "fk_616ddd680a", on_delete: :cascade
add_foreign_key "deploy_keys_projects", "projects", name: "fk_58a901ca7e", on_delete: :cascade
add_foreign_key "deployments", "clusters", name: "fk_289bba3222", on_delete: :nullify
add_foreign_key "deployments", "projects", name: "fk_b9a3851b82", on_delete: :cascade
add_foreign_key "design_management_designs", "issues", on_delete: :cascade
add_foreign_key "design_management_designs", "projects", on_delete: :cascade
......
......@@ -20,7 +20,7 @@ module Gitlab
private
def deployment_cluster
build.deployment&.deployment_platform_cluster
build.deployment&.cluster
end
def kubernetes_namespace
......
......@@ -22,6 +22,10 @@ FactoryBot.define do
ref 'pages-deploy'
end
trait :on_cluster do
cluster factory: %i(cluster provided_by_gcp)
end
trait :running do
status :running
end
......
......@@ -17,15 +17,12 @@ describe Gitlab::Ci::Build::Prerequisite::KubernetesNamespace do
end
context 'build has a deployment' do
let!(:deployment) { create(:deployment, deployable: build) }
let!(:deployment) { create(:deployment, deployable: build, cluster: cluster) }
let(:cluster) { nil }
context 'and a cluster to deploy to' do
let(:cluster) { create(:cluster, :group) }
before do
allow(build.deployment).to receive(:deployment_platform_cluster).and_return(cluster)
end
it { is_expected.to be_truthy }
context 'and the cluster is not managed' do
......@@ -48,28 +45,21 @@ describe Gitlab::Ci::Build::Prerequisite::KubernetesNamespace do
end
context 'and no cluster to deploy to' do
before do
expect(deployment.deployment_platform_cluster).to be_nil
end
it { is_expected.to be_falsey }
end
end
end
describe '#complete!' do
let!(:deployment) { create(:deployment, deployable: build) }
let!(:deployment) { create(:deployment, deployable: build, cluster: cluster) }
let(:service) { double(execute: true) }
let(:cluster) { nil }
subject { described_class.new(build).complete! }
context 'completion is required' do
let(:cluster) { create(:cluster, :group) }
before do
allow(build.deployment).to receive(:deployment_platform_cluster).and_return(cluster)
end
it 'creates a kubernetes namespace' do
expect(Clusters::Gcp::Kubernetes::CreateOrUpdateNamespaceService)
.to receive(:new)
......@@ -83,10 +73,6 @@ describe Gitlab::Ci::Build::Prerequisite::KubernetesNamespace do
end
context 'completion is not required' do
before do
expect(deployment.deployment_platform_cluster).to be_nil
end
it 'does not create a namespace' do
expect(Clusters::Gcp::Kubernetes::CreateOrUpdateNamespaceService).not_to receive(:new)
......
......@@ -7,10 +7,6 @@ describe Deployable do
let(:deployment) { job.deployment }
let(:environment) { deployment&.environment }
before do
job.reload
end
context 'when the deployable object will deploy to production' do
let!(:job) { create(:ci_build, :start_review_app) }
......@@ -26,6 +22,16 @@ describe Deployable do
end
end
context 'when the deployable object will deploy to a cluster' do
let(:project) { create(:project) }
let!(:cluster) { create(:cluster, :provided_by_user, projects: [project]) }
let!(:job) { create(:ci_build, :start_review_app, project: project) }
it 'creates a deployment with cluster association' do
expect(deployment.cluster).to eq(cluster)
end
end
context 'when the deployable object will stop an environment' do
let!(:job) { create(:ci_build, :stop_review_app) }
......
......@@ -7,6 +7,7 @@ describe Deployment do
it { is_expected.to belong_to(:project).required }
it { is_expected.to belong_to(:environment).required }
it { is_expected.to belong_to(:cluster).class_name('Clusters::Cluster') }
it { is_expected.to belong_to(:user) }
it { is_expected.to belong_to(:deployable) }
......@@ -294,6 +295,67 @@ describe Deployment do
end
end
describe '#has_metrics?' do
subject { deployment.has_metrics? }
context 'when deployment is failed' do
let(:deployment) { create(:deployment, :failed) }
it { is_expected.to be_falsy }
end
context 'when deployment is success' do
let(:deployment) { create(:deployment, :success) }
context 'without a monitoring service' do
it { is_expected.to be_falsy }
end
context 'with a Prometheus Service' do
let(:prometheus_service) { double(:prometheus_service, can_query?: true) }
before do
allow(deployment.project).to receive(:find_or_initialize_service).with('prometheus').and_return prometheus_service
end
it { is_expected.to be_truthy }
end
context 'with a Prometheus Service that cannot query' do
let(:prometheus_service) { double(:prometheus_service, can_query?: false) }
before do
allow(deployment.project).to receive(:find_or_initialize_service).with('prometheus').and_return prometheus_service
end
it { is_expected.to be_falsy }
end
context 'with a cluster Prometheus' do
let(:deployment) { create(:deployment, :success, :on_cluster) }
let!(:prometheus) { create(:clusters_applications_prometheus, :installed, cluster: deployment.cluster) }
before do
expect(deployment.cluster.application_prometheus).to receive(:can_query?).and_return(true)
end
it { is_expected.to be_truthy }
end
context 'fallback deployment platform' do
let(:cluster) { create(:cluster, :provided_by_user, environment_scope: '*', projects: [deployment.project]) }
let!(:prometheus) { create(:clusters_applications_prometheus, :installed, cluster: cluster) }
before do
expect(deployment.project).to receive(:deployment_platform).and_return(cluster.platform)
expect(cluster.application_prometheus).to receive(:can_query?).and_return(true)
end
it { is_expected.to be_truthy }
end
end
end
describe '#metrics' do
let(:deployment) { create(:deployment, :success) }
let(:prometheus_adapter) { double('prometheus_adapter', can_query?: true) }
......
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