summaryrefslogtreecommitdiff
path: root/spec/models/clusters
diff options
context:
space:
mode:
Diffstat (limited to 'spec/models/clusters')
-rw-r--r--spec/models/clusters/applications/elastic_stack_spec.rb70
-rw-r--r--spec/models/clusters/applications/fluentd_spec.rb36
-rw-r--r--spec/models/clusters/applications/ingress_spec.rb6
-rw-r--r--spec/models/clusters/applications/jupyter_spec.rb4
-rw-r--r--spec/models/clusters/cluster_spec.rb98
5 files changed, 194 insertions, 20 deletions
diff --git a/spec/models/clusters/applications/elastic_stack_spec.rb b/spec/models/clusters/applications/elastic_stack_spec.rb
index b0992c43d11..02ada219e32 100644
--- a/spec/models/clusters/applications/elastic_stack_spec.rb
+++ b/spec/models/clusters/applications/elastic_stack_spec.rb
@@ -19,10 +19,12 @@ describe Clusters::Applications::ElasticStack do
it 'is initialized with elastic stack arguments' do
expect(subject.name).to eq('elastic-stack')
- expect(subject.chart).to eq('stable/elastic-stack')
- expect(subject.version).to eq('1.9.0')
+ expect(subject.chart).to eq('elastic-stack/elastic-stack')
+ expect(subject.version).to eq('3.0.0')
+ expect(subject.repository).to eq('https://charts.gitlab.io')
expect(subject).to be_rbac
expect(subject.files).to eq(elastic_stack.files)
+ expect(subject.preinstall).to be_empty
end
context 'on a non rbac enabled cluster' do
@@ -33,15 +35,75 @@ describe Clusters::Applications::ElasticStack do
it { is_expected.not_to be_rbac }
end
+ context 'on versions older than 2' do
+ before do
+ elastic_stack.status = elastic_stack.status_states[:updating]
+ elastic_stack.version = "1.9.0"
+ end
+
+ it 'includes a preinstall script' do
+ expect(subject.preinstall).not_to be_empty
+ expect(subject.preinstall.first).to include("delete")
+ end
+ end
+
+ context 'on versions older than 3' do
+ before do
+ elastic_stack.status = elastic_stack.status_states[:updating]
+ elastic_stack.version = "2.9.0"
+ end
+
+ it 'includes a preinstall script' do
+ expect(subject.preinstall).not_to be_empty
+ expect(subject.preinstall.first).to include("delete")
+ end
+ end
+
context 'application failed to install previously' do
let(:elastic_stack) { create(:clusters_applications_elastic_stack, :errored, version: '0.0.1') }
it 'is initialized with the locked version' do
- expect(subject.version).to eq('1.9.0')
+ expect(subject.version).to eq('3.0.0')
end
end
end
+ describe '#chart_above_v2?' do
+ let(:elastic_stack) { create(:clusters_applications_elastic_stack, version: version) }
+
+ subject { elastic_stack.chart_above_v2? }
+
+ context 'on v1.9.0' do
+ let(:version) { '1.9.0' }
+
+ it { is_expected.to be_falsy }
+ end
+
+ context 'on v2.0.0' do
+ let(:version) { '2.0.0' }
+
+ it { is_expected.to be_truthy }
+ end
+ end
+
+ describe '#chart_above_v3?' do
+ let(:elastic_stack) { create(:clusters_applications_elastic_stack, version: version) }
+
+ subject { elastic_stack.chart_above_v3? }
+
+ context 'on v1.9.0' do
+ let(:version) { '1.9.0' }
+
+ it { is_expected.to be_falsy }
+ end
+
+ context 'on v3.0.0' do
+ let(:version) { '3.0.0' }
+
+ it { is_expected.to be_truthy }
+ end
+ end
+
describe '#uninstall_command' do
let!(:elastic_stack) { create(:clusters_applications_elastic_stack) }
@@ -57,7 +119,7 @@ describe Clusters::Applications::ElasticStack do
it 'specifies a post delete command to remove custom resource definitions' do
expect(subject.postdelete).to eq([
- 'kubectl delete pvc --selector release\\=elastic-stack'
+ 'kubectl delete pvc --selector app\\=elastic-stack-elasticsearch-master --namespace gitlab-managed-apps'
])
end
end
diff --git a/spec/models/clusters/applications/fluentd_spec.rb b/spec/models/clusters/applications/fluentd_spec.rb
index 7e9680b0ab4..4e9548990ed 100644
--- a/spec/models/clusters/applications/fluentd_spec.rb
+++ b/spec/models/clusters/applications/fluentd_spec.rb
@@ -3,7 +3,9 @@
require 'spec_helper'
describe Clusters::Applications::Fluentd do
- let(:fluentd) { create(:clusters_applications_fluentd) }
+ let(:waf_log_enabled) { true }
+ let(:cilium_log_enabled) { true }
+ let(:fluentd) { create(:clusters_applications_fluentd, waf_log_enabled: waf_log_enabled, cilium_log_enabled: cilium_log_enabled) }
include_examples 'cluster application core specs', :clusters_applications_fluentd
include_examples 'cluster application status specs', :clusters_applications_fluentd
@@ -47,4 +49,36 @@ describe Clusters::Applications::Fluentd do
expect(values).to include('output.conf', 'general.conf')
end
end
+
+ describe '#values' do
+ let(:modsecurity_log_path) { "/var/log/containers/*#{Clusters::Applications::Ingress::MODSECURITY_LOG_CONTAINER_NAME}*.log" }
+ let(:cilium_log_path) { "/var/log/containers/*#{described_class::CILIUM_CONTAINER_NAME}*.log" }
+
+ subject { fluentd.values }
+
+ context 'with both logs variables set to false' do
+ let(:waf_log_enabled) { false }
+ let(:cilium_log_enabled) { false }
+
+ it "raises ActiveRecord::RecordInvalid" do
+ expect {subject}.to raise_error(ActiveRecord::RecordInvalid)
+ end
+ end
+
+ context 'with both logs variables set to true' do
+ it { is_expected.to include("#{modsecurity_log_path},#{cilium_log_path}") }
+ end
+
+ context 'with waf_log_enabled set to true' do
+ let(:cilium_log_enabled) { false }
+
+ it { is_expected.to include(modsecurity_log_path) }
+ end
+
+ context 'with cilium_log_enabled set to true' do
+ let(:waf_log_enabled) { false }
+
+ it { is_expected.to include(cilium_log_path) }
+ end
+ end
end
diff --git a/spec/models/clusters/applications/ingress_spec.rb b/spec/models/clusters/applications/ingress_spec.rb
index b070729ccac..8aee4eec0d3 100644
--- a/spec/models/clusters/applications/ingress_spec.rb
+++ b/spec/models/clusters/applications/ingress_spec.rb
@@ -220,6 +220,12 @@ describe Clusters::Applications::Ingress do
expect(subject.values).to include('extraContainers')
end
+ it 'executes command to tail modsecurity logs with -F option' do
+ args = YAML.safe_load(subject.values).dig('controller', 'extraContainers', 0, 'args')
+
+ expect(args).to eq(['/bin/sh', '-c', 'tail -F /var/log/modsec/audit.log'])
+ end
+
it 'includes livenessProbe for modsecurity sidecar container' do
probe_config = YAML.safe_load(subject.values).dig('controller', 'extraContainers', 0, 'livenessProbe')
diff --git a/spec/models/clusters/applications/jupyter_spec.rb b/spec/models/clusters/applications/jupyter_spec.rb
index 3bc5088d1ab..937db9217f3 100644
--- a/spec/models/clusters/applications/jupyter_spec.rb
+++ b/spec/models/clusters/applications/jupyter_spec.rb
@@ -57,7 +57,7 @@ describe Clusters::Applications::Jupyter do
it 'is initialized with 4 arguments' do
expect(subject.name).to eq('jupyter')
expect(subject.chart).to eq('jupyter/jupyterhub')
- expect(subject.version).to eq('0.9.0-beta.2')
+ expect(subject.version).to eq('0.9.0')
expect(subject).to be_rbac
expect(subject.repository).to eq('https://jupyterhub.github.io/helm-chart/')
@@ -76,7 +76,7 @@ describe Clusters::Applications::Jupyter do
let(:jupyter) { create(:clusters_applications_jupyter, :errored, version: '0.0.1') }
it 'is initialized with the locked version' do
- expect(subject.version).to eq('0.9.0-beta.2')
+ expect(subject.version).to eq('0.9.0')
end
end
end
diff --git a/spec/models/clusters/cluster_spec.rb b/spec/models/clusters/cluster_spec.rb
index db1d8672d1e..521ed98f637 100644
--- a/spec/models/clusters/cluster_spec.rb
+++ b/spec/models/clusters/cluster_spec.rb
@@ -590,6 +590,60 @@ describe Clusters::Cluster, :use_clean_rails_memory_store_caching do
end
end
+ describe '#find_or_build_application' do
+ let_it_be(:cluster, reload: true) { create(:cluster) }
+
+ it 'rejects classes that are not applications' do
+ expect do
+ cluster.find_or_build_application(Project)
+ end.to raise_error(ArgumentError)
+ end
+
+ context 'when none of applications are created' do
+ it 'returns the new application', :aggregate_failures do
+ described_class::APPLICATIONS.values.each do |application_class|
+ application = cluster.find_or_build_application(application_class)
+
+ expect(application).to be_a(application_class)
+ expect(application).not_to be_persisted
+ end
+ end
+ end
+
+ context 'when application is persisted' do
+ let!(:helm) { create(:clusters_applications_helm, cluster: cluster) }
+ let!(:ingress) { create(:clusters_applications_ingress, cluster: cluster) }
+ let!(:cert_manager) { create(:clusters_applications_cert_manager, cluster: cluster) }
+ let!(:crossplane) { create(:clusters_applications_crossplane, cluster: cluster) }
+ let!(:prometheus) { create(:clusters_applications_prometheus, cluster: cluster) }
+ let!(:runner) { create(:clusters_applications_runner, cluster: cluster) }
+ let!(:jupyter) { create(:clusters_applications_jupyter, cluster: cluster) }
+ let!(:knative) { create(:clusters_applications_knative, cluster: cluster) }
+ let!(:elastic_stack) { create(:clusters_applications_elastic_stack, cluster: cluster) }
+ let!(:fluentd) { create(:clusters_applications_fluentd, cluster: cluster) }
+
+ it 'returns the persisted application', :aggregate_failures do
+ {
+ Clusters::Applications::Helm => helm,
+ Clusters::Applications::Ingress => ingress,
+ Clusters::Applications::CertManager => cert_manager,
+ Clusters::Applications::Crossplane => crossplane,
+ Clusters::Applications::Prometheus => prometheus,
+ Clusters::Applications::Runner => runner,
+ Clusters::Applications::Jupyter => jupyter,
+ Clusters::Applications::Knative => knative,
+ Clusters::Applications::ElasticStack => elastic_stack,
+ Clusters::Applications::Fluentd => fluentd
+ }.each do |application_class, expected_object|
+ application = cluster.find_or_build_application(application_class)
+
+ expect(application).to eq(expected_object)
+ expect(application).to be_persisted
+ end
+ end
+ end
+ end
+
describe '#allow_user_defined_namespace?' do
subject { cluster.allow_user_defined_namespace? }
@@ -889,9 +943,9 @@ describe Clusters::Cluster, :use_clean_rails_memory_store_caching do
end
describe '#make_cleanup_errored!' do
- NON_ERRORED_STATES = Clusters::Cluster.state_machines[:cleanup_status].states.keys - [:cleanup_errored]
+ non_errored_states = Clusters::Cluster.state_machines[:cleanup_status].states.keys - [:cleanup_errored]
- NON_ERRORED_STATES.each do |state|
+ non_errored_states.each do |state|
it "transitions cleanup_status from #{state} to cleanup_errored" do
cluster = create(:cluster, state)
@@ -948,6 +1002,22 @@ describe Clusters::Cluster, :use_clean_rails_memory_store_caching do
end
end
+ describe '#nodes' do
+ let(:cluster) { create(:cluster) }
+
+ subject { cluster.nodes }
+
+ it { is_expected.to be_nil }
+
+ context 'with a cached status' do
+ before do
+ stub_reactive_cache(cluster, nodes: [kube_node])
+ end
+
+ it { is_expected.to eq([kube_node]) }
+ end
+ end
+
describe '#calculate_reactive_cache' do
subject { cluster.calculate_reactive_cache }
@@ -956,6 +1026,7 @@ describe Clusters::Cluster, :use_clean_rails_memory_store_caching do
it 'does not populate the cache' do
expect(cluster).not_to receive(:retrieve_connection_status)
+ expect(cluster).not_to receive(:retrieve_nodes)
is_expected.to be_nil
end
@@ -964,12 +1035,12 @@ describe Clusters::Cluster, :use_clean_rails_memory_store_caching do
context 'cluster is enabled' do
let(:cluster) { create(:cluster, :provided_by_user, :group) }
- context 'connection to the cluster is successful' do
- before do
- stub_kubeclient_discover(cluster.platform.api_url)
- end
+ before do
+ stub_kubeclient_nodes_and_nodes_metrics(cluster.platform.api_url)
+ end
- it { is_expected.to eq(connection_status: :connected) }
+ context 'connection to the cluster is successful' do
+ it { is_expected.to eq(connection_status: :connected, nodes: [kube_node.merge(kube_node_metrics)]) }
end
context 'cluster cannot be reached' do
@@ -978,7 +1049,7 @@ describe Clusters::Cluster, :use_clean_rails_memory_store_caching do
.and_raise(SocketError)
end
- it { is_expected.to eq(connection_status: :unreachable) }
+ it { is_expected.to eq(connection_status: :unreachable, nodes: []) }
end
context 'cluster cannot be authenticated to' do
@@ -987,7 +1058,7 @@ describe Clusters::Cluster, :use_clean_rails_memory_store_caching do
.and_raise(OpenSSL::X509::CertificateError.new("Certificate error"))
end
- it { is_expected.to eq(connection_status: :authentication_failure) }
+ it { is_expected.to eq(connection_status: :authentication_failure, nodes: []) }
end
describe 'Kubeclient::HttpError' do
@@ -999,18 +1070,18 @@ describe Clusters::Cluster, :use_clean_rails_memory_store_caching do
.and_raise(Kubeclient::HttpError.new(error_code, error_message, nil))
end
- it { is_expected.to eq(connection_status: :authentication_failure) }
+ it { is_expected.to eq(connection_status: :authentication_failure, nodes: []) }
context 'generic timeout' do
let(:error_message) { 'Timed out connecting to server'}
- it { is_expected.to eq(connection_status: :unreachable) }
+ it { is_expected.to eq(connection_status: :unreachable, nodes: []) }
end
context 'gateway timeout' do
let(:error_message) { '504 Gateway Timeout for GET https://kubernetes.example.com/api/v1'}
- it { is_expected.to eq(connection_status: :unreachable) }
+ it { is_expected.to eq(connection_status: :unreachable, nodes: []) }
end
end
@@ -1020,11 +1091,12 @@ describe Clusters::Cluster, :use_clean_rails_memory_store_caching do
.and_raise(StandardError)
end
- it { is_expected.to eq(connection_status: :unknown_failure) }
+ it { is_expected.to eq(connection_status: :unknown_failure, nodes: []) }
it 'notifies Sentry' do
expect(Gitlab::ErrorTracking).to receive(:track_exception)
.with(instance_of(StandardError), hash_including(cluster_id: cluster.id))
+ .twice
subject
end