diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-04-16 03:09:22 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-04-16 03:09:22 +0300 |
commit | cf97983af87962e678412790363bba200a2be4b1 (patch) | |
tree | 2c16fc8a32b92d6e55fbda66796c0ea59e9bea61 | |
parent | 2eda658f34763b651b198365550c67d073439a12 (diff) |
Add latest changes from gitlab-org/gitlab@master
30 files changed, 436 insertions, 45 deletions
diff --git a/.markdownlint.json b/.markdownlint.json index 056a2fe560b..ce319756c5f 100644 --- a/.markdownlint.json +++ b/.markdownlint.json @@ -42,6 +42,7 @@ "CentOS", "Consul", "Debian", + "DevOps", "Elasticsearch", "Facebook", "Git LFS", @@ -85,6 +86,7 @@ "Microsoft", "Minikube", "MinIO", + "ModSecurity", "NGINX Ingress", "NGINX", "OAuth", diff --git a/app/assets/javascripts/clusters/services/application_state_machine.js b/app/assets/javascripts/clusters/services/application_state_machine.js index 6bc4be7b93a..6af9b10f12f 100644 --- a/app/assets/javascripts/clusters/services/application_state_machine.js +++ b/app/assets/javascripts/clusters/services/application_state_machine.js @@ -191,7 +191,8 @@ const applicationStateMachine = { * @param {*} event */ const transitionApplicationState = (application, event) => { - const newState = applicationStateMachine[application.status].on[event]; + const stateMachine = applicationStateMachine[application.status]; + const newState = stateMachine !== undefined ? stateMachine.on[event] : false; return newState ? { diff --git a/app/controllers/clusters/applications_controller.rb b/app/controllers/clusters/applications_controller.rb index 3ebd248c29e..de14bd319e0 100644 --- a/app/controllers/clusters/applications_controller.rb +++ b/app/controllers/clusters/applications_controller.rb @@ -47,7 +47,7 @@ class Clusters::ApplicationsController < Clusters::BaseController end def cluster_application_params - params.permit(:application, :hostname, :pages_domain_id, :email, :stack, :modsecurity_enabled, :modsecurity_mode) + params.permit(:application, :hostname, :pages_domain_id, :email, :stack, :modsecurity_enabled, :modsecurity_mode, :host, :port, :protocol) end def cluster_application_destroy_params diff --git a/app/finders/metrics/dashboards/annotations_finder.rb b/app/finders/metrics/dashboards/annotations_finder.rb new file mode 100644 index 00000000000..c42b8bf40e5 --- /dev/null +++ b/app/finders/metrics/dashboards/annotations_finder.rb @@ -0,0 +1,42 @@ +# frozen_string_literal: true + +module Metrics + module Dashboards + class AnnotationsFinder + def initialize(dashboard:, params:) + @dashboard, @params = dashboard, params + end + + def execute + if dashboard.environment + apply_filters_to(annotations_for_environment) + else + Metrics::Dashboard::Annotation.none + end + end + + private + + attr_reader :dashboard, :params + + def apply_filters_to(annotations) + annotations = annotations.after(params[:from]) if params[:from].present? + annotations = annotations.before(params[:to]) if params[:to].present? && valid_timespan_boundaries? + + by_dashboard(annotations) + end + + def annotations_for_environment + dashboard.environment.metrics_dashboard_annotations + end + + def by_dashboard(annotations) + annotations.for_dashboard(dashboard.path) + end + + def valid_timespan_boundaries? + params[:from].blank? || params[:to] >= params[:from] + end + end + end +end diff --git a/app/models/clusters/applications/fluentd.rb b/app/models/clusters/applications/fluentd.rb new file mode 100644 index 00000000000..a33b1e39ace --- /dev/null +++ b/app/models/clusters/applications/fluentd.rb @@ -0,0 +1,101 @@ +# frozen_string_literal: true + +module Clusters + module Applications + class Fluentd < ApplicationRecord + VERSION = '2.4.0' + + self.table_name = 'clusters_applications_fluentd' + + include ::Clusters::Concerns::ApplicationCore + include ::Clusters::Concerns::ApplicationStatus + include ::Clusters::Concerns::ApplicationVersion + include ::Clusters::Concerns::ApplicationData + + default_value_for :version, VERSION + default_value_for :port, 514 + default_value_for :protocol, :tcp + + enum protocol: { tcp: 0, udp: 1 } + + def chart + 'stable/fluentd' + end + + def install_command + Gitlab::Kubernetes::Helm::InstallCommand.new( + name: 'fluentd', + repository: repository, + version: VERSION, + rbac: cluster.platform_kubernetes_rbac?, + chart: chart, + files: files + ) + end + + def values + content_values.to_yaml + end + + private + + def content_values + YAML.load_file(chart_values_file).deep_merge!(specification) + end + + def specification + { + "configMaps" => { + "output.conf" => output_configuration_content, + "general.conf" => general_configuration_content + } + } + end + + def output_configuration_content + <<~EOF + <match kubernetes.**> + @type remote_syslog + @id out_kube_remote_syslog + host #{host} + port #{port} + program fluentd + hostname ${kubernetes_host} + protocol #{protocol} + packet_size 65535 + <buffer kubernetes_host> + </buffer> + <format> + @type ltsv + </format> + </match> + EOF + end + + def general_configuration_content + <<~EOF + <match fluent.**> + @type null + </match> + <source> + @type http + port 9880 + bind 0.0.0.0 + </source> + <source> + @type tail + @id in_tail_container_logs + path /var/log/containers/*#{Ingress::MODSECURITY_LOG_CONTAINER_NAME}*.log + pos_file /var/log/fluentd-containers.log.pos + tag kubernetes.* + read_from_head true + <parse> + @type json + time_format %Y-%m-%dT%H:%M:%S.%NZ + </parse> + </source> + EOF + end + end + end +end diff --git a/app/models/clusters/cluster.rb b/app/models/clusters/cluster.rb index 9ef3d64f21a..430a9b3c43e 100644 --- a/app/models/clusters/cluster.rb +++ b/app/models/clusters/cluster.rb @@ -19,7 +19,8 @@ module Clusters Clusters::Applications::Runner.application_name => Clusters::Applications::Runner, Clusters::Applications::Jupyter.application_name => Clusters::Applications::Jupyter, Clusters::Applications::Knative.application_name => Clusters::Applications::Knative, - Clusters::Applications::ElasticStack.application_name => Clusters::Applications::ElasticStack + Clusters::Applications::ElasticStack.application_name => Clusters::Applications::ElasticStack, + Clusters::Applications::Fluentd.application_name => Clusters::Applications::Fluentd }.freeze DEFAULT_ENVIRONMENT = '*' KUBE_INGRESS_BASE_DOMAIN = 'KUBE_INGRESS_BASE_DOMAIN' @@ -57,6 +58,7 @@ module Clusters has_one_cluster_application :jupyter has_one_cluster_application :knative has_one_cluster_application :elastic_stack + has_one_cluster_application :fluentd has_many :kubernetes_namespaces has_many :metrics_dashboard_annotations, class_name: 'Metrics::Dashboard::Annotation', inverse_of: :cluster diff --git a/app/models/metrics/dashboard/annotation.rb b/app/models/metrics/dashboard/annotation.rb index 2f1b6527742..8166880f0c9 100644 --- a/app/models/metrics/dashboard/annotation.rb +++ b/app/models/metrics/dashboard/annotation.rb @@ -15,6 +15,11 @@ module Metrics validate :single_ownership validate :orphaned_annotation + scope :after, ->(after) { where('starting_at >= ?', after) } + scope :before, ->(before) { where('starting_at <= ?', before) } + + scope :for_dashboard, ->(dashboard_path) { where(dashboard_path: dashboard_path) } + private def single_ownership diff --git a/app/models/project.rb b/app/models/project.rb index 443b44dd023..3168def7dd8 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -591,7 +591,7 @@ class Project < ApplicationRecord # # query - The search query as a String. def search(query, include_namespace: false) - if include_namespace && Feature.enabled?(:project_search_by_full_path, default_enabled: true) + if include_namespace joins(:route).fuzzy_search(query, [Route.arel_table[:path], Route.arel_table[:name], :description]) else fuzzy_search(query, [:path, :name, :description]) diff --git a/app/serializers/cluster_application_entity.rb b/app/serializers/cluster_application_entity.rb index c08691c6bcf..85a40f1f5cb 100644 --- a/app/serializers/cluster_application_entity.rb +++ b/app/serializers/cluster_application_entity.rb @@ -16,4 +16,7 @@ class ClusterApplicationEntity < Grape::Entity expose :available_domains, using: Serverless::DomainEntity, if: -> (e, _) { e.respond_to?(:available_domains) } expose :pages_domain, using: Serverless::DomainEntity, if: -> (e, _) { e.respond_to?(:pages_domain) } expose :modsecurity_mode, if: -> (e, _) { e.respond_to?(:modsecurity_mode) } + expose :host, if: -> (e, _) { e.respond_to?(:host) } + expose :port, if: -> (e, _) { e.respond_to?(:port) } + expose :protocol, if: -> (e, _) { e.respond_to?(:protocol) } end diff --git a/app/services/clusters/applications/base_service.rb b/app/services/clusters/applications/base_service.rb index bd4ce693085..86b48b5228d 100644 --- a/app/services/clusters/applications/base_service.rb +++ b/app/services/clusters/applications/base_service.rb @@ -35,6 +35,18 @@ module Clusters application.modsecurity_mode = params[:modsecurity_mode] || 0 end + if application.has_attribute?(:host) + application.host = params[:host] + end + + if application.has_attribute?(:protocol) + application.protocol = params[:protocol] + end + + if application.has_attribute?(:port) + application.port = params[:port] + end + if application.respond_to?(:oauth_application) application.oauth_application = create_oauth_application(application, request) end diff --git a/app/services/groups/import_export/import_service.rb b/app/services/groups/import_export/import_service.rb index 548a4a98dc1..f62b9d3c8a6 100644 --- a/app/services/groups/import_export/import_service.rb +++ b/app/services/groups/import_export/import_service.rb @@ -33,10 +33,12 @@ module Groups end def restorer - @restorer ||= Gitlab::ImportExport::Group::TreeRestorer.new(user: @current_user, - shared: @shared, - group: @group, - group_hash: nil) + @restorer ||= Gitlab::ImportExport::Group::LegacyTreeRestorer.new( + user: @current_user, + shared: @shared, + group: @group, + group_hash: nil + ) end def remove_import_file diff --git a/changelogs/unreleased/add_fluentd_model_as_cluster_app.yml b/changelogs/unreleased/add_fluentd_model_as_cluster_app.yml new file mode 100644 index 00000000000..fea6440f41e --- /dev/null +++ b/changelogs/unreleased/add_fluentd_model_as_cluster_app.yml @@ -0,0 +1,5 @@ +--- +title: Add Fluentd model for cluster apps +merge_request: 28846 +author: +type: changed diff --git a/doc/ci/junit_test_reports.md b/doc/ci/junit_test_reports.md index a97d4b865c8..c79db6dfbea 100644 --- a/doc/ci/junit_test_reports.md +++ b/doc/ci/junit_test_reports.md @@ -88,7 +88,7 @@ ruby: stage: test script: - bundle install - - rspec spec/lib/ --format RspecJunitFormatter --out rspec.xml + - bundle exec rspec --format progress --format RspecJunitFormatter --out rspec.xml artifacts: paths: - rspec.xml diff --git a/doc/development/contributing/issue_workflow.md b/doc/development/contributing/issue_workflow.md index c8705a174af..13ff35ed65c 100644 --- a/doc/development/contributing/issue_workflow.md +++ b/doc/development/contributing/issue_workflow.md @@ -113,7 +113,7 @@ Stage labels respects the `devops::<stage_key>` naming convention. <https://gitlab.com/gitlab-com/www-gitlab-com/blob/master/data/stages.yml> with `_` replaced with a space. -For instance, the "Manage" stage is represented by the ~"devops::manage" label in +For instance, the "Manage" stage is represented by the `~"devops::manage"` label in the `gitlab-org` group since its key under `stages` is `manage`. The current stage labels can be found by [searching the labels list for `devops::`](https://gitlab.com/groups/gitlab-org/-/labels?search=devops::). @@ -156,10 +156,10 @@ As a team needs some way to collect the work their members are planning to be as Normally there is a 1:1 relationship between Stage labels and Group labels. In the spirit of "Everyone can contribute", any issue can be picked up by any group, depending on current priorities. When picking up an issue belonging to a different -group, it should be relabelled. For example, if an issue labelled ~"devops::create" -and ~"group::knowledge" is picked up by someone in the Access group of the Plan stage, -the issue should be relabelled as ~"group::access" while keeping the original -~"devops::create" unchanged. +group, it should be relabelled. For example, if an issue labelled `~"devops::create"` +and `~"group::knowledge"` is picked up by someone in the Access group of the Plan stage, +the issue should be relabelled as `~"group::access"` while keeping the original +`~"devops::create"` unchanged. We also use stage and group labels to help quantify our [throughput](https://about.gitlab.com/handbook/engineering/management/throughput/). Please read [Stage and Group labels in Throughput](https://about.gitlab.com/handbook/engineering/management/throughput/#stage-and-group-labels-in-throughput) for more information on how the labels are used in this context. diff --git a/doc/topics/airgap/index.md b/doc/topics/airgap/index.md index 44589c7e5f8..e712e3bb6b5 100644 --- a/doc/topics/airgap/index.md +++ b/doc/topics/airgap/index.md @@ -18,7 +18,7 @@ Follow these best practices to use GitLab's features in an offline environment: To use many GitLab features, including [security scans](../../user/application_security/index.md#working-in-an-offline-environment) -and [Auto Devops](../autodevops/), the GitLab Runner must be able to fetch the +and [Auto DevOps](../autodevops/), the GitLab Runner must be able to fetch the relevant Docker images. The process for making these images available without direct access to the public internet diff --git a/doc/topics/autodevops/stages.md b/doc/topics/autodevops/stages.md index 72fa3870abd..66b76dcc05a 100644 --- a/doc/topics/autodevops/stages.md +++ b/doc/topics/autodevops/stages.md @@ -474,7 +474,7 @@ To enable ModSecurity with Auto Deploy, you need to create a `.gitlab/auto-deplo |Attribute | Description | Default | -----------|-------------|---------| -|`enabled` | Enables custom configuration for modsecurity, defaulting to the [Core Rule Set](https://coreruleset.org/) | `false` | +|`enabled` | Enables custom configuration for ModSecurity, defaulting to the [Core Rule Set](https://coreruleset.org/) | `false` | |`secRuleEngine` | Configures the [rules engine](https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual-(v2.x)#secruleengine) | `DetectionOnly` | |`secRules` | Creates one or more additional [rule](https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual-(v2.x)#SecRule) | `nil` | diff --git a/doc/topics/web_application_firewall/quick_start_guide.md b/doc/topics/web_application_firewall/quick_start_guide.md index 6483a56e7f7..d55ab03a3f2 100644 --- a/doc/topics/web_application_firewall/quick_start_guide.md +++ b/doc/topics/web_application_firewall/quick_start_guide.md @@ -213,7 +213,7 @@ the WAF with OWASP CRS! ## Testing out the OWASP Core Rule Set Now let's send a potentially malicious request, as if we were a scanner, -checking for vulnerabilities within our application and examine the modsecurity logs: +checking for vulnerabilities within our application and examine the ModSecurity logs: ```shell $ curl --location --insecure fjdiaz-auto-devv-2.34.68.60.207.nip.io --header "User-Agent: absinthe" | grep 'Rails!' --after 2 --before 2 diff --git a/doc/user/project/repository/forking_workflow.md b/doc/user/project/repository/forking_workflow.md index c26f2bd6b1d..126144de703 100644 --- a/doc/user/project/repository/forking_workflow.md +++ b/doc/user/project/repository/forking_workflow.md @@ -34,6 +34,12 @@ CAUTION: **Caution:** In GitLab 12.6 and later, when project owners [reduce a project's visibility](../../../public_access/public_access.md#reducing-visibility), it **removes the relationship** between a project and all its forks. +CAUTION: **Caution:** +When a public project with the repository feature set to "Members +only" is forked, the repository will be public in the fork. The owner +of the fork will need to manually change the visibility. This is being +fixed in [#36662](https://gitlab.com/gitlab-org/gitlab/-/issues/36662). + ## Repository mirroring You can use [repository mirroring](repository_mirroring.md) to keep your fork synced with the original repository. You can also use `git remote add upstream` to achieve the same result. diff --git a/lib/gitlab/error_tracking.rb b/lib/gitlab/error_tracking.rb index a6e49825fd0..b893d625f8d 100644 --- a/lib/gitlab/error_tracking.rb +++ b/lib/gitlab/error_tracking.rb @@ -186,7 +186,7 @@ module Gitlab return event unless CUSTOM_FINGERPRINTING.include?(ex.class.name) - event.fingerprint = ['{{ default }}', ex.class.name, ex.message] + event.fingerprint = [ex.class.name, ex.message] event end diff --git a/lib/gitlab/import_export/group/tree_restorer.rb b/lib/gitlab/import_export/group/legacy_tree_restorer.rb index 323e6727a9f..5d96a0f3c0a 100644 --- a/lib/gitlab/import_export/group/tree_restorer.rb +++ b/lib/gitlab/import_export/group/legacy_tree_restorer.rb @@ -3,7 +3,7 @@ module Gitlab module ImportExport module Group - class TreeRestorer + class LegacyTreeRestorer include Gitlab::Utils::StrongMemoize attr_reader :user diff --git a/spec/factories/clusters/applications/helm.rb b/spec/factories/clusters/applications/helm.rb index 0a4f0fba9ab..728c83e01b4 100644 --- a/spec/factories/clusters/applications/helm.rb +++ b/spec/factories/clusters/applications/helm.rb @@ -139,5 +139,14 @@ FactoryBot.define do cluster factory: %i(cluster provided_by_gcp) end end + + factory :clusters_applications_fluentd, class: 'Clusters::Applications::Fluentd' do + host { 'example.com' } + cluster factory: %i(cluster with_installed_helm provided_by_gcp) + + trait :no_helm_installed do + cluster factory: %i(cluster provided_by_gcp) + end + end end end diff --git a/spec/finders/metrics/dashboards/annotations_finder_spec.rb b/spec/finders/metrics/dashboards/annotations_finder_spec.rb new file mode 100644 index 00000000000..222875ba2e2 --- /dev/null +++ b/spec/finders/metrics/dashboards/annotations_finder_spec.rb @@ -0,0 +1,107 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Metrics::Dashboards::AnnotationsFinder do + describe '#execute' do + subject(:annotations) { described_class.new(dashboard: dashboard, params: params).execute } + + let_it_be(:current_user) { create(:user) } + let(:path) { 'config/prometheus/common_metrics.yml' } + let(:params) { {} } + let(:environment) { create(:environment) } + let(:dashboard) { PerformanceMonitoring::PrometheusDashboard.new(path: path, environment: environment) } + + context 'there are no annotations records' do + it 'returns empty array' do + expect(annotations).to be_empty + end + end + + context 'with annotation records' do + let!(:nine_minutes_old_annotation) { create(:metrics_dashboard_annotation, environment: environment, starting_at: 9.minutes.ago, dashboard_path: path) } + let!(:fifteen_minutes_old_annotation) { create(:metrics_dashboard_annotation, environment: environment, starting_at: 15.minutes.ago, dashboard_path: path) } + let!(:just_created_annotation) { create(:metrics_dashboard_annotation, environment: environment, dashboard_path: path) } + let!(:annotation_for_different_env) { create(:metrics_dashboard_annotation, dashboard_path: path) } + let!(:annotation_for_different_dashboard) { create(:metrics_dashboard_annotation, dashboard_path: '.gitlab/dashboards/test.yml') } + + it 'loads annotations' do + expect(annotations).to match_array [fifteen_minutes_old_annotation, nine_minutes_old_annotation, just_created_annotation] + end + + context 'when the from filter is present' do + let(:params) do + { + from: 14.minutes.ago + } + end + + it 'loads only younger annotations' do + expect(annotations).to match_array [nine_minutes_old_annotation, just_created_annotation] + end + end + + context 'when the to filter is present' do + let(:params) do + { + to: 5.minutes.ago + } + end + + it 'loads only older annotations' do + expect(annotations).to match_array [fifteen_minutes_old_annotation, nine_minutes_old_annotation] + end + end + + context 'when from and to filters are present' do + context 'and to is bigger than from' do + let(:params) do + { + from: 14.minutes.ago, + to: 5.minutes.ago + } + end + + it 'loads only annotations assigned to this interval' do + expect(annotations).to match_array [nine_minutes_old_annotation] + end + end + + context 'and from is bigger than to' do + let(:params) do + { + to: 14.minutes.ago, + from: 5.minutes.ago + } + end + + it 'ignores to parameter and returns annotations starting at from filter' do + expect(annotations).to match_array [just_created_annotation] + end + end + + context 'when from or to filters are empty strings' do + let(:params) do + { + from: '', + to: '' + } + end + + it 'ignores this parameters' do + expect(annotations).to match_array [fifteen_minutes_old_annotation, nine_minutes_old_annotation, just_created_annotation] + end + end + end + + context 'dashboard environment is missing' do + let(:dashboard) { PerformanceMonitoring::PrometheusDashboard.new(path: path, environment: nil) } + + it 'returns empty relation', :aggregate_failures do + expect(annotations).to be_kind_of ::ActiveRecord::Relation + expect(annotations).to be_empty + end + end + end + end +end diff --git a/spec/fixtures/api/schemas/cluster_status.json b/spec/fixtures/api/schemas/cluster_status.json index ba97b7c82cb..ce62655648b 100644 --- a/spec/fixtures/api/schemas/cluster_status.json +++ b/spec/fixtures/api/schemas/cluster_status.json @@ -39,6 +39,9 @@ "stack": { "type": ["string", "null"] }, "modsecurity_enabled": { "type": ["boolean", "null"] }, "modsecurity_mode": {"type": ["integer", "0"]}, + "host": {"type": ["string", "null"]}, + "port": {"type": ["integer", "514"]}, + "protocol": {"type": ["integer", "0"]}, "update_available": { "type": ["boolean", "null"] }, "can_uninstall": { "type": "boolean" }, "available_domains": { diff --git a/spec/frontend/clusters/services/application_state_machine_spec.js b/spec/frontend/clusters/services/application_state_machine_spec.js index 8632c5c4e26..b27cd2c80fd 100644 --- a/spec/frontend/clusters/services/application_state_machine_spec.js +++ b/spec/frontend/clusters/services/application_state_machine_spec.js @@ -161,4 +161,20 @@ describe('applicationStateMachine', () => { }); }); }); + + describe('current state is undefined', () => { + it('returns the current state without having any effects', () => { + const currentAppState = {}; + expect(transitionApplicationState(currentAppState, INSTALLABLE)).toEqual(currentAppState); + }); + }); + + describe('with event is undefined', () => { + it('returns the current state without having any effects', () => { + const currentAppState = { + status: NO_STATUS, + }; + expect(transitionApplicationState(currentAppState, undefined)).toEqual(currentAppState); + }); + }); }); diff --git a/spec/lib/gitlab/import_export/group/tree_restorer_spec.rb b/spec/lib/gitlab/import_export/group/legacy_tree_restorer_spec.rb index fc7e4737d13..3030cdf4cf8 100644 --- a/spec/lib/gitlab/import_export/group/tree_restorer_spec.rb +++ b/spec/lib/gitlab/import_export/group/legacy_tree_restorer_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -describe Gitlab::ImportExport::Group::TreeRestorer do +describe Gitlab::ImportExport::Group::LegacyTreeRestorer do include ImportExport::CommonUtil let(:shared) { Gitlab::ImportExport::Shared.new(group) } diff --git a/spec/models/clusters/applications/fluentd_spec.rb b/spec/models/clusters/applications/fluentd_spec.rb new file mode 100644 index 00000000000..7e9680b0ab4 --- /dev/null +++ b/spec/models/clusters/applications/fluentd_spec.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Clusters::Applications::Fluentd do + let(:fluentd) { create(:clusters_applications_fluentd) } + + include_examples 'cluster application core specs', :clusters_applications_fluentd + include_examples 'cluster application status specs', :clusters_applications_fluentd + include_examples 'cluster application version specs', :clusters_applications_fluentd + include_examples 'cluster application initial status specs' + + describe '#can_uninstall?' do + subject { fluentd.can_uninstall? } + + it { is_expected.to be true } + end + + describe '#install_command' do + subject { fluentd.install_command } + + it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::InstallCommand) } + + it 'is initialized with fluentd arguments' do + expect(subject.name).to eq('fluentd') + expect(subject.chart).to eq('stable/fluentd') + expect(subject.version).to eq('2.4.0') + expect(subject).to be_rbac + end + + context 'application failed to install previously' do + let(:fluentd) { create(:clusters_applications_fluentd, :errored, version: '0.0.1') } + + it 'is initialized with the locked version' do + expect(subject.version).to eq('2.4.0') + end + end + end + + describe '#files' do + let(:application) { fluentd } + let(:values) { subject[:'values.yaml'] } + + subject { application.files } + + it 'includes fluentd specific keys in the values.yaml file' do + expect(values).to include('output.conf', 'general.conf') + end + end +end diff --git a/spec/models/clusters/cluster_spec.rb b/spec/models/clusters/cluster_spec.rb index 29c75186110..db1d8672d1e 100644 --- a/spec/models/clusters/cluster_spec.rb +++ b/spec/models/clusters/cluster_spec.rb @@ -582,9 +582,10 @@ describe Clusters::Cluster, :use_clean_rails_memory_store_caching do 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 a list of created applications' do - is_expected.to contain_exactly(helm, ingress, cert_manager, crossplane, prometheus, runner, jupyter, knative, elastic_stack) + is_expected.to contain_exactly(helm, ingress, cert_manager, crossplane, prometheus, runner, jupyter, knative, elastic_stack, fluentd) end end end diff --git a/spec/models/metrics/dashboard/annotation_spec.rb b/spec/models/metrics/dashboard/annotation_spec.rb index ed3bef37a7c..f7fd7ded7e6 100644 --- a/spec/models/metrics/dashboard/annotation_spec.rb +++ b/spec/models/metrics/dashboard/annotation_spec.rb @@ -50,4 +50,30 @@ describe Metrics::Dashboard::Annotation do end end end + + describe 'scopes' do + let_it_be(:nine_minutes_old_annotation) { create(:metrics_dashboard_annotation, starting_at: 9.minutes.ago) } + let_it_be(:fifteen_minutes_old_annotation) { create(:metrics_dashboard_annotation, starting_at: 15.minutes.ago) } + let_it_be(:just_created_annotation) { create(:metrics_dashboard_annotation) } + + describe '#after' do + it 'returns only younger annotations' do + expect(described_class.after(12.minutes.ago)).to match_array [nine_minutes_old_annotation, just_created_annotation] + end + end + + describe '#before' do + it 'returns only older annotations' do + expect(described_class.before(5.minutes.ago)).to match_array [fifteen_minutes_old_annotation, nine_minutes_old_annotation] + end + end + + describe '#for_dashboard' do + let!(:other_dashboard_annotation) { create(:metrics_dashboard_annotation, dashboard_path: 'other_dashboard.yml') } + + it 'returns annotations only for appointed dashboard' do + expect(described_class.for_dashboard('other_dashboard.yml')).to match_array [other_dashboard_annotation] + end + end + end end diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index 3c8afee4466..6d4283ab666 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -1740,32 +1740,12 @@ describe Project do let_it_be(:group) { create(:group) } let_it_be(:project) { create(:project, group: group) } - context 'when feature is enabled' do - before do - stub_feature_flags(project_search_by_full_path: true) - end - - it 'returns projects that match the group path' do - expect(described_class.search(group.path, include_namespace: true)).to eq([project]) - end - - it 'returns projects that match the full path' do - expect(described_class.search(project.full_path, include_namespace: true)).to eq([project]) - end + it 'returns projects that match the group path' do + expect(described_class.search(group.path, include_namespace: true)).to eq([project]) end - context 'when feature is disabled' do - before do - stub_feature_flags(project_search_by_full_path: false) - end - - it 'returns no results when searching by group path' do - expect(described_class.search(group.path, include_namespace: true)).to be_empty - end - - it 'returns no results when searching by full path' do - expect(described_class.search(project.full_path, include_namespace: true)).to be_empty - end + it 'returns projects that match the full path' do + expect(described_class.search(project.full_path, include_namespace: true)).to eq([project]) end end diff --git a/vendor/fluentd/values.yaml b/vendor/fluentd/values.yaml new file mode 100644 index 00000000000..a5072ef14ae --- /dev/null +++ b/vendor/fluentd/values.yaml @@ -0,0 +1,18 @@ +plugins: + enabled: true + pluginsList: ["fluent-plugin-remote_syslog"] + +extraVolumes: + - name: varlog + hostPath: + path: /var/log + - name: varlibdockercontainers + hostPath: + path: /var/lib/docker/containers + +extraVolumeMounts: + - name: varlog + mountPath: /var/log + - name: varlibdockercontainers + mountPath: /var/lib/docker/containers + readOnly: true |