diff options
Diffstat (limited to 'spec/models/clusters')
-rw-r--r-- | spec/models/clusters/applications/elastic_stack_spec.rb | 70 | ||||
-rw-r--r-- | spec/models/clusters/applications/fluentd_spec.rb | 36 | ||||
-rw-r--r-- | spec/models/clusters/applications/ingress_spec.rb | 6 | ||||
-rw-r--r-- | spec/models/clusters/applications/jupyter_spec.rb | 4 | ||||
-rw-r--r-- | spec/models/clusters/cluster_spec.rb | 98 |
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 |