Commit e33ecfde authored by Tiger's avatar Tiger

Disable JIT resource creation for project clusters

JIT resource creation blocks deployments if a user is
self-managing their cluster, as it will fail the build
if unable to create a namespace and service account.

Using a custom namespace and service account was previously
supported for project level clusters, so we should preserve
this functionality.

https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/27352
parent 0a99e022
No related merge requests found
......@@ -21,7 +21,11 @@ module Clusters
private_class_method :projects_with_missing_kubernetes_namespaces_for_cluster
def self.clusters_with_missing_kubernetes_namespaces_for_project(project)
project.all_clusters.missing_kubernetes_namespace(project.kubernetes_namespaces)
if Feature.enabled?(:ci_preparing_state, default_enabled: true)
project.clusters.missing_kubernetes_namespace(project.kubernetes_namespaces)
else
project.all_clusters.missing_kubernetes_namespace(project.kubernetes_namespaces)
end
end
private_class_method :clusters_with_missing_kubernetes_namespaces_for_project
......
......@@ -5,10 +5,10 @@ class ClusterConfigureWorker
include ClusterQueue
def perform(cluster_id)
return if Feature.enabled?(:ci_preparing_state, default_enabled: true)
Clusters::Cluster.find_by_id(cluster_id).try do |cluster|
Clusters::RefreshService.create_or_update_namespaces_for_cluster(cluster)
if cluster.project_type? || Feature.disabled?(:ci_preparing_state, default_enabled: true)
Clusters::RefreshService.create_or_update_namespaces_for_cluster(cluster)
end
end
end
end
......@@ -5,8 +5,6 @@ class ClusterProjectConfigureWorker
include ClusterQueue
def perform(project_id)
return if Feature.enabled?(:ci_preparing_state, default_enabled: true)
project = Project.find(project_id)
::Clusters::RefreshService.create_or_update_namespaces_for_project(project)
......
---
title: Disable just-in-time Kubernetes resource creation for project level clusters
merge_request: 27352
author:
type: changed
......@@ -565,7 +565,9 @@ service account of the cluster integration.
### Troubleshooting failed deployment jobs
GitLab will create a namespace and service account specifically for your
deployment jobs, immediately before the jobs starts.
deployment jobs. On project level clusters, this happens when the cluster
is created. On group level clusters, resources are created immediately
before the deployment job starts.
However, sometimes GitLab can not create them. In such instances, your job will fail with the message:
......
......@@ -6,7 +6,9 @@ module Gitlab
module Prerequisite
class KubernetesNamespace < Base
def unmet?
deployment_cluster.present? && kubernetes_namespace.new_record?
deployment_cluster.present? &&
!deployment_cluster.project_type? &&
kubernetes_namespace.new_record?
end
def complete!
......
......@@ -20,7 +20,7 @@ describe Gitlab::Ci::Build::Prerequisite::KubernetesNamespace do
let!(:deployment) { create(:deployment, deployable: build) }
context 'and a cluster to deploy to' do
let(:cluster) { create(:cluster, projects: [build.project]) }
let(:cluster) { create(:cluster, :group) }
before do
allow(build.deployment).to receive(:cluster).and_return(cluster)
......@@ -33,6 +33,12 @@ describe Gitlab::Ci::Build::Prerequisite::KubernetesNamespace do
it { is_expected.to be_falsey }
end
context 'and cluster is project type' do
let(:cluster) { create(:cluster, :project) }
it { is_expected.to be_falsey }
end
end
context 'and no cluster to deploy to' do
......@@ -52,7 +58,7 @@ describe Gitlab::Ci::Build::Prerequisite::KubernetesNamespace do
subject { described_class.new(build).complete! }
context 'completion is required' do
let(:cluster) { create(:cluster, projects: [build.project]) }
let(:cluster) { create(:cluster, :group) }
before do
allow(build.deployment).to receive(:cluster).and_return(cluster)
......
......@@ -93,14 +93,32 @@ describe Clusters::RefreshService do
let(:group) { cluster.group }
let(:project) { create(:project, group: group) }
include_examples 'creates a kubernetes namespace'
context 'when ci_preparing_state feature flag is enabled' do
include_examples 'does not create a kubernetes namespace'
context 'when project already has kubernetes namespace' do
context 'when project already has kubernetes namespace' do
before do
create(:cluster_kubernetes_namespace, project: project, cluster: cluster)
end
include_examples 'does not create a kubernetes namespace'
end
end
context 'when ci_preparing_state feature flag is disabled' do
before do
create(:cluster_kubernetes_namespace, project: project, cluster: cluster)
stub_feature_flags(ci_preparing_state: false)
end
include_examples 'does not create a kubernetes namespace'
include_examples 'creates a kubernetes namespace'
context 'when project already has kubernetes namespace' do
before do
create(:cluster_kubernetes_namespace, project: project, cluster: cluster)
end
include_examples 'does not create a kubernetes namespace'
end
end
end
end
......
......@@ -10,25 +10,35 @@ describe ClusterConfigureWorker, '#perform' do
stub_feature_flags(ci_preparing_state: ci_preparing_state_enabled)
end
context 'when group cluster' do
let(:cluster) { create(:cluster, :group, :provided_by_gcp) }
let(:group) { cluster.group }
shared_examples 'configured cluster' do
it 'creates a namespace' do
expect(Clusters::RefreshService).to receive(:create_or_update_namespaces_for_cluster).with(cluster).once
context 'when group has no projects' do
it 'does not create a namespace' do
expect_any_instance_of(Clusters::Gcp::Kubernetes::CreateOrUpdateNamespaceService).not_to receive(:execute)
worker.perform(cluster.id)
end
end
worker.perform(cluster.id)
end
shared_examples 'unconfigured cluster' do
it 'does not create a namespace' do
expect(Clusters::RefreshService).not_to receive(:create_or_update_namespaces_for_cluster)
worker.perform(cluster.id)
end
end
context 'group cluster' do
let(:cluster) { create(:cluster, :group, :provided_by_gcp) }
let(:group) { cluster.group }
context 'when group has a project' do
let!(:project) { create(:project, group: group) }
it 'creates a namespace for the project' do
expect_any_instance_of(Clusters::Gcp::Kubernetes::CreateOrUpdateNamespaceService).to receive(:execute).once
it_behaves_like 'configured cluster'
context 'ci_preparing_state feature is enabled' do
let(:ci_preparing_state_enabled) { true }
worker.perform(cluster.id)
it_behaves_like 'unconfigured cluster'
end
end
......@@ -36,32 +46,26 @@ describe ClusterConfigureWorker, '#perform' do
let!(:subgroup) { create(:group, parent: group) }
let!(:project) { create(:project, group: subgroup) }
it 'creates a namespace for the project' do
expect_any_instance_of(Clusters::Gcp::Kubernetes::CreateOrUpdateNamespaceService).to receive(:execute).once
it_behaves_like 'configured cluster'
worker.perform(cluster.id)
context 'ci_preparing_state feature is enabled' do
let(:ci_preparing_state_enabled) { true }
it_behaves_like 'unconfigured cluster'
end
end
end
context 'when provider type is gcp' do
let(:cluster) { create(:cluster, :project, :provided_by_gcp) }
it 'configures kubernetes platform' do
expect_any_instance_of(Clusters::Gcp::Kubernetes::CreateOrUpdateNamespaceService).to receive(:execute)
let!(:cluster) { create(:cluster, :project, :provided_by_gcp) }
described_class.new.perform(cluster.id)
end
it_behaves_like 'configured cluster'
end
context 'when provider type is user' do
let(:cluster) { create(:cluster, :project, :provided_by_user) }
let!(:cluster) { create(:cluster, :project, :provided_by_user) }
it 'configures kubernetes platform' do
expect_any_instance_of(Clusters::Gcp::Kubernetes::CreateOrUpdateNamespaceService).to receive(:execute)
described_class.new.perform(cluster.id)
end
it_behaves_like 'configured cluster'
end
context 'when cluster does not exist' do
......@@ -71,15 +75,4 @@ describe ClusterConfigureWorker, '#perform' do
described_class.new.perform(123)
end
end
context 'ci_preparing_state feature is enabled' do
let(:cluster) { create(:cluster) }
let(:ci_preparing_state_enabled) { true }
it 'does not configure the cluster' do
expect(Clusters::RefreshService).not_to receive(:create_or_update_namespaces_for_cluster)
described_class.new.perform(cluster.id)
end
end
end
......@@ -4,18 +4,11 @@ require 'spec_helper'
describe ClusterProjectConfigureWorker, '#perform' do
let(:worker) { described_class.new }
let(:cluster) { create(:cluster, :project) }
context 'ci_preparing_state feature is enabled' do
let(:cluster) { create(:cluster) }
it 'configures the cluster' do
expect(Clusters::RefreshService).to receive(:create_or_update_namespaces_for_project)
before do
stub_feature_flags(ci_preparing_state: true)
end
it 'does not configure the cluster' do
expect(Clusters::RefreshService).not_to receive(:create_or_update_namespaces_for_project)
described_class.new.perform(cluster.id)
end
described_class.new.perform(cluster.projects.first.id)
end
end
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