Commit 98a14a49 authored by Tiger's avatar Tiger

Add build prerequisite for Kubernetes namespaces

Builds that have deployments require Kubernetes resources
to be created before the build can be deployed. These
resources are no longer created when the cluster is
created, which allows us to only create the resources
required by each specific build.
parent 00f0d356
---
title: Create Kubernetes resources for projects when their deployment jobs run.
merge_request: 25586
author:
type: changed
......@@ -8,7 +8,7 @@ module Gitlab
attr_reader :build
def self.prerequisites
[]
[KubernetesNamespace]
end
def initialize(build)
......
# frozen_string_literal: true
module Gitlab
module Ci
module Build
module Prerequisite
class KubernetesNamespace < Base
##
# Cluster settings may have changed since the last deploy,
# so we must always ensure the namespace is up to date.
#
def unmet?
build.has_deployment? && clusters_missing_namespaces.present?
end
def complete!
return unless unmet?
clusters_missing_namespaces.each do |cluster|
create_or_update_namespace(cluster)
end
end
private
def project
build.project
end
def create_or_update_namespace(cluster)
kubernetes_namespace = cluster.find_or_initialize_kubernetes_namespace_for_project(project)
Clusters::Gcp::Kubernetes::CreateOrUpdateNamespaceService.new(
cluster: cluster,
kubernetes_namespace: kubernetes_namespace
).execute
end
def clusters_missing_namespaces
strong_memoize(:clusters_missing_namespaces) do
project.all_clusters.missing_kubernetes_namespace(project.kubernetes_namespaces).to_a
end
end
end
end
end
end
end
# frozen_string_literal: true
require 'spec_helper'
describe Gitlab::Ci::Build::Prerequisite::KubernetesNamespace do
let(:build) { create(:ci_build) }
describe '#unmet?' do
subject { described_class.new(build).unmet? }
context 'build has no deployment' do
before do
expect(build.deployment).to be_nil
end
it { is_expected.to be_falsey }
end
context 'build has a deployment, and no existing kubernetes namespace' do
let!(:deployment) { create(:deployment, deployable: build) }
let!(:cluster) { create(:cluster, projects: [build.project]) }
before do
expect(build.project.kubernetes_namespaces).to be_empty
end
it { is_expected.to be_truthy }
end
context 'build has a deployment and kubernetes namespaces' do
let!(:deployment) { create(:deployment, deployable: build) }
let!(:cluster) { create(:cluster, projects: [build.project]) }
let!(:kubernetes_namespace) { create(:cluster_kubernetes_namespace, cluster: cluster) }
it { is_expected.to be_falsey }
end
end
describe '#complete!' do
let(:cluster) { create(:cluster, projects: [build.project]) }
let(:service) { double(execute: true) }
subject { described_class.new(build).complete! }
context 'completion is required' do
let!(:deployment) { create(:deployment, deployable: build) }
it 'creates a kubernetes namespace' do
expect(Clusters::Gcp::Kubernetes::CreateOrUpdateNamespaceService)
.to receive(:new)
.with(cluster: cluster, kubernetes_namespace: instance_of(Clusters::KubernetesNamespace))
.and_return(service)
expect(service).to receive(:execute).once
subject
end
end
context 'completion is not required' do
before do
expect(build.deployment).to be_nil
end
it 'does not create a namespace' do
expect(Clusters::Gcp::Kubernetes::CreateOrUpdateNamespaceService).not_to receive(:new)
subject
end
end
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