Commit e1789478 authored by Kamil Trzciński's avatar Kamil Trzciński

Merge branch '5347-fix-multiple-clusters-incorrect-details-injected' into 'master'

Resolve "Multiple clusters: incorrect cluster details injected - environment scope is ignored"

Closes #5347

See merge request gitlab-org/gitlab-ee!5047
parents b769f211 bc600786
...@@ -11,6 +11,7 @@ module Clusters ...@@ -11,6 +11,7 @@ module Clusters
Applications::Prometheus.application_name => Applications::Prometheus, Applications::Prometheus.application_name => Applications::Prometheus,
Applications::Runner.application_name => Applications::Runner Applications::Runner.application_name => Applications::Runner
}.freeze }.freeze
DEFAULT_ENVIRONMENT = '*'.freeze
belongs_to :user belongs_to :user
...@@ -52,6 +53,7 @@ module Clusters ...@@ -52,6 +53,7 @@ module Clusters
scope :enabled, -> { where(enabled: true) } scope :enabled, -> { where(enabled: true) }
scope :disabled, -> { where(enabled: false) } scope :disabled, -> { where(enabled: false) }
scope :default_environment, -> { where(environment_scope: DEFAULT_ENVIRONMENT) }
def status_name def status_name
if provider if provider
......
module DeploymentPlatform module DeploymentPlatform
# EE would override this and utilize the extra argument # EE would override this and utilize environment argument
# rubocop:disable Gitlab/ModuleWithInstanceVariables
def deployment_platform(environment: nil) def deployment_platform(environment: nil)
@deployment_platform ||= @deployment_platform ||= {}
find_cluster_platform_kubernetes ||
find_kubernetes_service_integration || @deployment_platform[environment] ||= find_deployment_platform(environment)
build_cluster_and_deployment_platform
end end
private private
def find_cluster_platform_kubernetes def find_deployment_platform(environment)
clusters.find_by(enabled: true)&.platform_kubernetes find_cluster_platform_kubernetes(environment: environment) ||
find_kubernetes_service_integration ||
build_cluster_and_deployment_platform
end
# EE would override this and utilize environment argument
def find_cluster_platform_kubernetes(environment: nil)
clusters.enabled.default_environment
.last&.platform_kubernetes
end end
def find_kubernetes_service_integration def find_kubernetes_service_integration
......
...@@ -2,15 +2,12 @@ module EE ...@@ -2,15 +2,12 @@ module EE
module DeploymentPlatform module DeploymentPlatform
extend ::Gitlab::Utils::Override extend ::Gitlab::Utils::Override
override :deployment_platform override :find_cluster_platform_kubernetes
def deployment_platform(environment: nil) def find_cluster_platform_kubernetes(environment: nil)
return super unless environment && feature_available?(:multiple_clusters) return super unless environment && feature_available?(:multiple_clusters)
@deployment_platform ||= # rubocop:disable Gitlab/ModuleWithInstanceVariables clusters.enabled.on_environment(environment.name)
clusters.enabled.on_environment(environment.name) .last&.platform_kubernetes
.last&.platform_kubernetes
super # Wildcard or KubernetesService
end end
end end
end end
---
title: Fixes incorrect assignation of cluster details
merge_request: 5047
author:
type: fixed
...@@ -17,7 +17,7 @@ describe 'Project show page', :feature do ...@@ -17,7 +17,7 @@ describe 'Project show page', :feature do
it '"Kubernetes cluster" button linked to clusters page' do it '"Kubernetes cluster" button linked to clusters page' do
create(:cluster, :provided_by_gcp, projects: [project]) create(:cluster, :provided_by_gcp, projects: [project])
create(:cluster, :provided_by_gcp, projects: [project]) create(:cluster, :provided_by_gcp, :production_environment, projects: [project])
visit project_path(project) visit project_path(project)
......
...@@ -4,56 +4,56 @@ describe EE::DeploymentPlatform do ...@@ -4,56 +4,56 @@ describe EE::DeploymentPlatform do
describe '#deployment_platform' do describe '#deployment_platform' do
let(:project) { create(:project) } let(:project) { create(:project) }
context 'when environment is specified' do shared_examples 'matching environment scope' do
let(:environment) { create(:environment, project: project, name: 'review/name') } context 'when multiple clusters license is available' do
let!(:default_cluster) { create(:cluster, :provided_by_user, projects: [project], environment_scope: '*') } before do
let!(:cluster) { create(:cluster, :provided_by_user, environment_scope: 'review/*', projects: [project]) } stub_licensed_features(multiple_clusters: true)
end
subject { project.deployment_platform(environment: environment) }
shared_examples 'matching environment scope' do
context 'when multiple clusters is available' do
before do
stub_licensed_features(multiple_clusters: true)
end
it 'returns environment specific cluster' do it 'returns environment specific cluster' do
is_expected.to eq(cluster.platform_kubernetes) is_expected.to eq(cluster.platform_kubernetes)
end
end end
end
context 'when multiple clusters is unavailable' do context 'when multiple clusters licence is unavailable' do
before do before do
stub_licensed_features(multiple_clusters: false) stub_licensed_features(multiple_clusters: false)
end end
it 'returns a kubernetes platform' do it 'returns a kubernetes platform' do
is_expected.to be_kind_of(Clusters::Platforms::Kubernetes) is_expected.to be_kind_of(Clusters::Platforms::Kubernetes)
end
end end
end end
end
shared_examples 'not matching environment scope' do shared_examples 'not matching environment scope' do
context 'when multiple clusters is available' do context 'when multiple clusters license is available' do
before do before do
stub_licensed_features(multiple_clusters: true) stub_licensed_features(multiple_clusters: true)
end end
it 'returns default cluster' do it 'returns default cluster' do
is_expected.to eq(default_cluster.platform_kubernetes) is_expected.to eq(default_cluster.platform_kubernetes)
end
end end
end
context 'when multiple clusters is unavailable' do context 'when multiple clusters license is unavailable' do
before do before do
stub_licensed_features(multiple_clusters: false) stub_licensed_features(multiple_clusters: false)
end end
it 'returns a kubernetes platform' do it 'returns a kubernetes platform' do
is_expected.to be_kind_of(Clusters::Platforms::Kubernetes) is_expected.to be_kind_of(Clusters::Platforms::Kubernetes)
end
end end
end end
end
context 'when environment is specified' do
let!(:default_cluster) { create(:cluster, :provided_by_user, projects: [project], environment_scope: '*') }
let!(:cluster) { create(:cluster, :provided_by_user, environment_scope: 'review/*', projects: [project]) }
let(:environment) { create(:environment, project: project, name: 'review/name') }
subject { project.deployment_platform(environment: environment) }
context 'when environment scope is exactly matched' do context 'when environment scope is exactly matched' do
before do before do
...@@ -133,5 +133,21 @@ describe EE::DeploymentPlatform do ...@@ -133,5 +133,21 @@ describe EE::DeploymentPlatform do
end end
end end
end end
context 'with multiple clusters and multiple environments' do
let!(:cluster_1) { create(:cluster, :provided_by_user, projects: [project], environment_scope: 'staging/*') }
let!(:cluster_2) { create(:cluster, :provided_by_user, projects: [project], environment_scope: 'test/*') }
let(:environment_1) { create(:environment, project: project, name: 'staging/name') }
let(:environment_2) { create(:environment, project: project, name: 'test/name') }
before do
stub_licensed_features(multiple_clusters: true)
end
it 'should return the appropriate cluster' do
expect(project.deployment_platform(environment: environment_1)).to eq(cluster_1.platform_kubernetes)
expect(project.deployment_platform(environment: environment_2)).to eq(cluster_2.platform_kubernetes)
end
end
end end
end end
...@@ -18,7 +18,7 @@ describe Projects::ClustersController do ...@@ -18,7 +18,7 @@ describe Projects::ClustersController do
context 'when project has one or more clusters' do context 'when project has one or more clusters' do
let(:project) { create(:project) } let(:project) { create(:project) }
let!(:enabled_cluster) { create(:cluster, :provided_by_gcp, projects: [project]) } let!(:enabled_cluster) { create(:cluster, :provided_by_gcp, projects: [project]) }
let!(:disabled_cluster) { create(:cluster, :disabled, :provided_by_gcp, projects: [project]) } let!(:disabled_cluster) { create(:cluster, :disabled, :provided_by_gcp, :production_environment, projects: [project]) }
it 'lists available clusters' do it 'lists available clusters' do
go go
...@@ -32,7 +32,7 @@ describe Projects::ClustersController do ...@@ -32,7 +32,7 @@ describe Projects::ClustersController do
before do before do
allow(Clusters::Cluster).to receive(:paginates_per).and_return(1) allow(Clusters::Cluster).to receive(:paginates_per).and_return(1)
create_list(:cluster, 2, :provided_by_gcp, projects: [project]) create_list(:cluster, 2, :provided_by_gcp, :production_environment, projects: [project])
get :index, namespace_id: project.namespace, project_id: project, page: last_page get :index, namespace_id: project.namespace, project_id: project, page: last_page
end end
...@@ -420,7 +420,7 @@ describe Projects::ClustersController do ...@@ -420,7 +420,7 @@ describe Projects::ClustersController do
context 'when cluster is provided by GCP' do context 'when cluster is provided by GCP' do
context 'when cluster is created' do context 'when cluster is created' do
let!(:cluster) { create(:cluster, :provided_by_gcp, projects: [project]) } let!(:cluster) { create(:cluster, :provided_by_gcp, :production_environment, projects: [project]) }
it "destroys and redirects back to clusters list" do it "destroys and redirects back to clusters list" do
expect { go } expect { go }
...@@ -434,7 +434,7 @@ describe Projects::ClustersController do ...@@ -434,7 +434,7 @@ describe Projects::ClustersController do
end end
context 'when cluster is being created' do context 'when cluster is being created' do
let!(:cluster) { create(:cluster, :providing_by_gcp, projects: [project]) } let!(:cluster) { create(:cluster, :providing_by_gcp, :production_environment, projects: [project]) }
it "destroys and redirects back to clusters list" do it "destroys and redirects back to clusters list" do
expect { go } expect { go }
...@@ -448,7 +448,7 @@ describe Projects::ClustersController do ...@@ -448,7 +448,7 @@ describe Projects::ClustersController do
end end
context 'when cluster is provided by user' do context 'when cluster is provided by user' do
let!(:cluster) { create(:cluster, :provided_by_user, projects: [project]) } let!(:cluster) { create(:cluster, :provided_by_user, :production_environment, projects: [project]) }
it "destroys and redirects back to clusters list" do it "destroys and redirects back to clusters list" do
expect { go } expect { go }
...@@ -463,7 +463,7 @@ describe Projects::ClustersController do ...@@ -463,7 +463,7 @@ describe Projects::ClustersController do
end end
describe 'security' do describe 'security' do
set(:cluster) { create(:cluster, :provided_by_gcp, projects: [project]) } set(:cluster) { create(:cluster, :provided_by_gcp, :production_environment, projects: [project]) }
it { expect { go }.to be_allowed_for(:admin) } it { expect { go }.to be_allowed_for(:admin) }
it { expect { go }.to be_allowed_for(:owner).of(project) } it { expect { go }.to be_allowed_for(:owner).of(project) }
......
...@@ -2,7 +2,6 @@ FactoryBot.define do ...@@ -2,7 +2,6 @@ FactoryBot.define do
factory :cluster, class: Clusters::Cluster do factory :cluster, class: Clusters::Cluster do
user user
name 'test-cluster' name 'test-cluster'
sequence(:environment_scope) { |n| "production#{n}/*" }
trait :project do trait :project do
before(:create) do |cluster, evaluator| before(:create) do |cluster, evaluator|
...@@ -33,5 +32,9 @@ FactoryBot.define do ...@@ -33,5 +32,9 @@ FactoryBot.define do
trait :disabled do trait :disabled do
enabled false enabled false
end end
trait :production_environment do
sequence(:environment_scope) { |n| "production#{n}/*" }
end
end end
end end
...@@ -6,7 +6,7 @@ describe ClustersFinder do ...@@ -6,7 +6,7 @@ describe ClustersFinder do
describe '#execute' do describe '#execute' do
let(:enabled_cluster) { create(:cluster, :provided_by_gcp, projects: [project]) } let(:enabled_cluster) { create(:cluster, :provided_by_gcp, projects: [project]) }
let(:disabled_cluster) { create(:cluster, :disabled, :provided_by_gcp, projects: [project]) } let(:disabled_cluster) { create(:cluster, :disabled, :provided_by_gcp, :production_environment, projects: [project]) }
subject { described_class.new(project, user, scope).execute } subject { described_class.new(project, user, scope).execute }
......
...@@ -378,7 +378,7 @@ describe Environment do ...@@ -378,7 +378,7 @@ describe Environment do
shared_examples 'same behavior between KubernetesService and Platform::Kubernetes' do shared_examples 'same behavior between KubernetesService and Platform::Kubernetes' do
it 'returns the terminals from the deployment service' do it 'returns the terminals from the deployment service' do
expect(project.deployment_platform) expect(project.deployment_platform(environment: environment))
.to receive(:terminals).with(environment) .to receive(:terminals).with(environment)
.and_return(:fake_terminals) .and_return(:fake_terminals)
...@@ -419,7 +419,7 @@ describe Environment do ...@@ -419,7 +419,7 @@ describe Environment do
end end
it 'returns the rollout status from the deployment service' do it 'returns the rollout status from the deployment service' do
expect(project.deployment_platform) expect(project.deployment_platform(environment: environment))
.to receive(:rollout_status).with(environment) .to receive(:rollout_status).with(environment)
.and_return(:fake_rollout_status) .and_return(:fake_rollout_status)
......
...@@ -339,7 +339,7 @@ describe ProjectPresenter do ...@@ -339,7 +339,7 @@ describe ProjectPresenter do
it 'returns link to clusters page if more than one exists' do it 'returns link to clusters page if more than one exists' do
project.add_master(user) project.add_master(user)
create(:cluster, projects: [project]) create(:cluster, :production_environment, projects: [project])
create(:cluster, projects: [project]) create(:cluster, projects: [project])
expect(presenter.kubernetes_cluster_anchor_data).to eq(OpenStruct.new(enabled: true, expect(presenter.kubernetes_cluster_anchor_data).to eq(OpenStruct.new(enabled: true,
......
...@@ -81,7 +81,7 @@ describe Clusters::CreateService do ...@@ -81,7 +81,7 @@ describe Clusters::CreateService do
end end
context 'when project has a cluster' do context 'when project has a cluster' do
let!(:cluster) { create(:cluster, :provided_by_gcp, projects: [project]) } let!(:cluster) { create(:cluster, :provided_by_gcp, :production_environment, projects: [project]) }
before do before do
allow(project).to receive(:feature_available?).and_call_original allow(project).to receive(:feature_available?).and_call_original
......
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