diff --git a/app/assets/javascripts/related_issues/constants.js b/app/assets/javascripts/related_issues/constants.js index 3516836952f..3d365eb1c30 100644 --- a/app/assets/javascripts/related_issues/constants.js +++ b/app/assets/javascripts/related_issues/constants.js @@ -114,7 +114,7 @@ export const PathIdSeparator = { }; export const issuablesBlockHeaderTextMap = { - [issuableTypesMap.ISSUE]: __('Linked issues'), + [issuableTypesMap.ISSUE]: __('Linked items'), [issuableTypesMap.INCIDENT]: __('Related incidents or issues'), [issuableTypesMap.EPIC]: __('Linked epics'), }; diff --git a/config/environments/development.rb b/config/environments/development.rb index 5b72c6b35f8..945026844cc 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -25,6 +25,9 @@ Rails.application.configure do # Print deprecation notices to the Rails logger config.active_support.deprecation = :log + # Raise exceptions for disallowed deprecations. + config.active_support.disallowed_deprecation = :raise + # Raise an error on page load if there are pending migrations config.active_record.migration_error = :page_load diff --git a/config/environments/production.rb b/config/environments/production.rb index b56aadb8b11..943307bde44 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -68,6 +68,9 @@ Rails.application.configure do # Send deprecation notices to registered listeners config.active_support.deprecation = :notify + # Silence disallowed deprecations. + config.active_support.disallowed_deprecation = :silence + config.action_mailer.delivery_method = :sendmail # Defaults to: # # config.action_mailer.sendmail_settings = { diff --git a/config/environments/test.rb b/config/environments/test.rb index 2935e0c7636..3671e37c0f3 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -49,6 +49,9 @@ Rails.application.configure do # Print deprecation notices to the stderr config.active_support.deprecation = :stderr + # Raise exceptions for disallowed deprecations. + config.active_support.disallowed_deprecation = :raise + config.eager_load = Gitlab::Utils.to_boolean(ENV['GITLAB_TEST_EAGER_LOAD'], default: ENV['CI'].present?) config.cache_store = :null_store diff --git a/config/initializers/00_deprecations.rb b/config/initializers/00_deprecations.rb new file mode 100644 index 00000000000..c768cf8d414 --- /dev/null +++ b/config/initializers/00_deprecations.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +# Disallowed deprecation warnings are silenced in production. For performance +# reasons we even skip the definition of disallowed warnings in production. +# +# See +# * https://gitlab.com/gitlab-org/gitlab/-/issues/368379 for a follow-up +# * https://gitlab.com/gitlab-org/gitlab/-/merge_requests/92557#note_1032212676 +# for benchmarks +# +# In Rails 7 we will use `config.active_support.report_deprecations = false` +# instead of this early return. +return if Rails.env.production? + +# Ban the following deprecation warnings and turn them into runtime errors +# in `development` and `test` environments. +# +# This way we prevent already fixed warnings from sneaking back into the codebase silently. +rails7_deprecation_warnings = [ + # https://gitlab.com/gitlab-org/gitlab/-/issues/339739 + /ActiveModel::Errors#keys is deprecated/, + # https://gitlab.com/gitlab-org/gitlab/-/issues/342492 + /Rendering actions with '\.' in the name is deprecated/, + # https://gitlab.com/gitlab-org/gitlab/-/issues/333086 + /default_hash is deprecated/ +] + +ActiveSupport::Deprecation.disallowed_warnings.concat rails7_deprecation_warnings diff --git a/db/post_migrate/20220525201022_add_temporary_index_for_vulnerability_reads_cluster_agent_id_migration.rb b/db/post_migrate/20220525201022_add_temporary_index_for_vulnerability_reads_cluster_agent_id_migration.rb new file mode 100644 index 00000000000..b795a41e9cd --- /dev/null +++ b/db/post_migrate/20220525201022_add_temporary_index_for_vulnerability_reads_cluster_agent_id_migration.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +class AddTemporaryIndexForVulnerabilityReadsClusterAgentIdMigration < Gitlab::Database::Migration[2.0] + INDEX_VULNERABILITY_READS_NAME = 'tmp_index_cis_vulnerability_reads_on_id' + + disable_ddl_transaction! + + def up + # this index is used in 20220525221133_schedule_backfill_vulnerability_reads_cluster_agent + add_concurrent_index :vulnerability_reads, :id, name: INDEX_VULNERABILITY_READS_NAME, where: 'report_type = 7' + end + + def down + remove_concurrent_index_by_name :vulnerability_reads, INDEX_VULNERABILITY_READS_NAME + end +end diff --git a/db/post_migrate/20220525221133_schedule_backfill_vulnerability_reads_cluster_agent.rb b/db/post_migrate/20220525221133_schedule_backfill_vulnerability_reads_cluster_agent.rb new file mode 100644 index 00000000000..bf83781e89c --- /dev/null +++ b/db/post_migrate/20220525221133_schedule_backfill_vulnerability_reads_cluster_agent.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +class ScheduleBackfillVulnerabilityReadsClusterAgent < Gitlab::Database::Migration[2.0] + restrict_gitlab_migration gitlab_schema: :gitlab_main + + BATCH_SIZE = 10_000 + SUB_BATCH_SIZE = 1_000 + DELAY_INTERVAL = 2.minutes + MIGRATION_NAME = 'BackfillVulnerabilityReadsClusterAgent' + BATCH_CLASS_NAME = 'BackfillVulnerabilityReadsClusterAgentBatchingStrategy' + + disable_ddl_transaction! + + def up + queue_batched_background_migration( + MIGRATION_NAME, + :vulnerability_reads, + :id, + job_interval: DELAY_INTERVAL, + batch_size: BATCH_SIZE, + batch_class_name: BATCH_CLASS_NAME, + sub_batch_size: SUB_BATCH_SIZE + ) + end + + def down + delete_batched_background_migration(MIGRATION_NAME, :vulnerability_reads, :id, []) + end +end diff --git a/db/schema_migrations/20220525201022 b/db/schema_migrations/20220525201022 new file mode 100644 index 00000000000..7b4ce7c509c --- /dev/null +++ b/db/schema_migrations/20220525201022 @@ -0,0 +1 @@ +c2b2fc7674b99791f6d239e42add7db3c72f2b27e653e2348887d0178f77686a \ No newline at end of file diff --git a/db/schema_migrations/20220525221133 b/db/schema_migrations/20220525221133 new file mode 100644 index 00000000000..0e78ee5df45 --- /dev/null +++ b/db/schema_migrations/20220525221133 @@ -0,0 +1 @@ +b22a0dd285d383f556a5402441f3e82a6db6dd47008444b94303351b295b414e \ No newline at end of file diff --git a/db/structure.sql b/db/structure.sql index 40e660df87e..5eb6bef1af9 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -30305,6 +30305,8 @@ CREATE INDEX tmp_index_ci_job_artifacts_on_expire_at_where_locked_unknown ON ci_ CREATE INDEX tmp_index_ci_job_artifacts_on_id_where_trace_and_expire_at ON ci_job_artifacts USING btree (id) WHERE ((file_type = 3) AND (expire_at = ANY (ARRAY['2021-04-22 00:00:00+00'::timestamp with time zone, '2021-05-22 00:00:00+00'::timestamp with time zone, '2021-06-22 00:00:00+00'::timestamp with time zone, '2022-01-22 00:00:00+00'::timestamp with time zone, '2022-02-22 00:00:00+00'::timestamp with time zone, '2022-03-22 00:00:00+00'::timestamp with time zone, '2022-04-22 00:00:00+00'::timestamp with time zone]))); +CREATE INDEX tmp_index_cis_vulnerability_reads_on_id ON vulnerability_reads USING btree (id) WHERE (report_type = 7); + CREATE INDEX tmp_index_container_repositories_on_id_migration_state ON container_repositories USING btree (id, migration_state); CREATE INDEX tmp_index_for_namespace_id_migration_on_group_members ON members USING btree (id) WHERE ((member_namespace_id IS NULL) AND ((type)::text = 'GroupMember'::text)); diff --git a/doc/api/repositories.md b/doc/api/repositories.md index 34b86902271..8138e06b9d3 100644 --- a/doc/api/repositories.md +++ b/doc/api/repositories.md @@ -319,7 +319,7 @@ Supported attributes: | `date` | datetime | no | The date and time of the release, defaults to the current time. | | `branch` | string | no | The branch to commit the changelog changes to, defaults to the project's default branch. | | `trailer` | string | no | The Git trailer to use for including commits, defaults to `Changelog`. | -| `config_file` | string | no | The path of changelog configuration file in the project's Git repository, defaults to `.gitlab/changelog_config.yml`. | +| `config_file` | string | no | Path to the changelog configuration file in the project's Git repository. Defaults to `.gitlab/changelog_config.yml`. | | `file` | string | no | The file to commit the changes to, defaults to `CHANGELOG.md`. | | `message` | string | no | The commit message to produce when committing the changes, defaults to `Add changelog for version X` where X is the value of the `version` argument. | diff --git a/doc/development/fips_compliance.md b/doc/development/fips_compliance.md index 6261b2fda6f..fa3524100b7 100644 --- a/doc/development/fips_compliance.md +++ b/doc/development/fips_compliance.md @@ -12,12 +12,9 @@ to ensure a certain security floor is met by vendors selling products to U.S. Federal institutions. WARNING: -GitLab is not FIPS compliant, even when built and run on a FIPS-enforcing -system. Large parts of the build are broken, and many features use forbidden -cryptographic primitives. Running GitLab on a FIPS-enforcing system is not -supported and may result in data loss. This document is intended to help -engineers looking to develop FIPS-related fixes. It is not intended to be used -to run a production GitLab instance. +You can build a FIPS-compliant instance of GitLab, but [not all features are included](#unsupported-features-in-fips-mode). +A FIPS-compliant instance must be configured following the [FIPS install instructions](#install-gitlab-with-fips-compliance) +exactly. There are two current FIPS standards: [140-2](https://en.wikipedia.org/wiki/FIPS_140-2) and [140-3](https://en.wikipedia.org/wiki/FIPS_140-3). At GitLab we usually @@ -25,10 +22,7 @@ mean FIPS 140-2. ## Current status -Read [Epic &5104](https://gitlab.com/groups/gitlab-org/-/epics/5104) for more -information on the status of the investigation. - -GitLab is actively working towards FIPS compliance. +GitLab is actively working towards FIPS compliance. Progress on this initiative can be tracked with this [FIPS compliance Epic](https://gitlab.com/groups/gitlab-org/-/epics/6452). ## FIPS compliance at GitLab @@ -56,6 +50,29 @@ The supported hybrid environments are: - Omnibus: Ubuntu 20.04 FIPS - EKS: Amazon Linux 2 +### Unsupported features in FIPS mode + +Some GitLab features may not work when FIPS mode is enabled. The following features +are known to not work in FIPS mode. However, there may be additional features not +listed here that also do not work properly in FIPS mode: + +- [Container Scanning](../user/application_security/container_scanning/index.md) support for scanning images in repositories that require authentication. +- [Code Quality](../ci/testing/code_quality.md) does not support operating in FIPS-compliant mode. +- [Dependency scanning](../user/application_security/dependency_scanning/index.md) support for Gradle. +- [Dynamic Application Security Testing (DAST)](../user/application_security/dast/index.md) + does not support operating in FIPS-compliant mode. +- [License compliance](../user/compliance/license_compliance/index.md). +- [Solutions for vulnerabilities](../user/application_security/vulnerabilities/index.md#resolve-a-vulnerability) + for yarn projects. +- [Static Application Security Testing (SAST)](../user/application_security/sast/index.md) + supports a reduced set of [analyzers](../user/application_security/sast/#fips-enabled-images) + when operating in FIPS-compliant mode. + +Additionally, these package repositories are disabled in FIPS mode: + +- [Conan package repository](../user/packages/conan_repository/index.md). +- [Debian package repository](../user/packages/debian_repository/index.md). + ## FIPS validation at GitLab Unlike FIPS compliance, FIPS validation is a formal declaration of compliance by @@ -417,29 +434,6 @@ def default_min_key_size(name) end ``` -#### Unsupported features in FIPS mode - -Some GitLab features may not work when FIPS mode is enabled. The following features -are known to not work in FIPS mode. However, there may be additional features not -listed here that also do not work properly in FIPS mode: - -- [Container Scanning](../user/application_security/container_scanning/index.md) support for scanning images in repositories that require authentication. -- [Code Quality](../ci/testing/code_quality.md) does not support operating in FIPS-compliant mode. -- [Dependency scanning](../user/application_security/dependency_scanning/index.md) support for Gradle. -- [Dynamic Application Security Testing (DAST)](../user/application_security/dast/index.md) - does not support operating in FIPS-compliant mode. -- [License compliance](../user/compliance/license_compliance/index.md). -- [Solutions for vulnerabilities](../user/application_security/vulnerabilities/index.md#resolve-a-vulnerability) - for yarn projects. -- [Static Application Security Testing (SAST)](../user/application_security/sast/index.md) - supports a reduced set of [analyzers](../user/application_security/sast/#fips-enabled-images) - when operating in FIPS-compliant mode. - -Additionally, these package repositories are disabled in FIPS mode: - -- [Conan package repository](../user/packages/conan_repository/index.md). -- [Debian package repository](../user/packages/debian_repository/index.md). - ## Nightly Omnibus FIPS builds The Distribution team has created [nightly FIPS Omnibus builds](https://packages.gitlab.com/gitlab/nightly-fips-builds). These diff --git a/doc/user/application_security/iac_scanning/index.md b/doc/user/application_security/iac_scanning/index.md index 35968a6361f..a14bc34550d 100644 --- a/doc/user/application_security/iac_scanning/index.md +++ b/doc/user/application_security/iac_scanning/index.md @@ -130,3 +130,24 @@ The IaC tool emits a JSON report file in the existing SAST report format. For mo The JSON report file can be downloaded from the CI pipelines page, or the pipelines tab on merge requests by [setting `artifacts: paths`](../../../ci/yaml/index.md#artifactspaths) to `gl-sast-report.json`. For more information see [Downloading artifacts](../../../ci/pipelines/job_artifacts.md). + +## Troubleshooting + +### IaC debug logging + +To help troubleshoot IaC jobs, you can increase the [Secure scanner log verbosity](../sast/index.md#logging-level) +by using a global CI/CD variable set to `debug`: + +```yaml +variables: + SECURE_LOG_LEVEL: "debug" +``` + +### IaC Scanning findings show as `No longer detected` unexpectedly + +If a previously detected finding unexpectedly shows as `No longer detected`, it might +be due to an update to the scanner. An update can disable rules that are found to +be ineffective or false positives, and the findings are marked as `No longer detected`: + +- In GitLab 15.3, [secret detection in the KICS SAST IaC scanner was disabled](https://gitlab.com/gitlab-org/gitlab/-/issues/346181), + so IaC findings in the "Passwords and Secrets" family show as `No longer detected`. diff --git a/doc/user/clusters/agent/gitops.md b/doc/user/clusters/agent/gitops.md index 73a35ffbc64..4978b56917b 100644 --- a/doc/user/clusters/agent/gitops.md +++ b/doc/user/clusters/agent/gitops.md @@ -4,10 +4,11 @@ group: Configure info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments --- -# Using GitOps with a Kubernetes cluster **(PREMIUM)** +# Using GitOps with a Kubernetes cluster **(FREE)** > - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/259669) in GitLab 13.7. > - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/332227) in GitLab 14.0, the `resource_inclusions` and `resource_exclusions` attributes were removed and `reconcile_timeout`, `dry_run_strategy`, `prune`, `prune_timeout`, `prune_propagation_policy`, and `inventory_policy` attributes were added. +> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/346567) from GitLab Premium to GitLab Free in 15.3. With GitOps, you can manage containerized clusters and applications from a Git repository that: diff --git a/doc/user/infrastructure/clusters/deploy/inventory_object.md b/doc/user/infrastructure/clusters/deploy/inventory_object.md index d184d969ace..fc3b86776f0 100644 --- a/doc/user/infrastructure/clusters/deploy/inventory_object.md +++ b/doc/user/infrastructure/clusters/deploy/inventory_object.md @@ -4,9 +4,10 @@ group: Configure info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments --- -# Tracking cluster resources managed by GitLab **(PREMIUM)** +# Tracking cluster resources managed by GitLab **(FREE)** -> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/332227) in GitLab 14.0. +> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/332227) in GitLab 14.0. +> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/346567) from GitLab Premium to GitLab Free in 15.3. GitLab uses an inventory object to track the resources you deploy to your cluster. The inventory object is a `ConfigMap` that contains a list of controlled objects. diff --git a/doc/user/markdown.md b/doc/user/markdown.md index b1e6fcb2f4e..9d9d330ac8e 100644 --- a/doc/user/markdown.md +++ b/doc/user/markdown.md @@ -1398,6 +1398,42 @@ For example: 1. Another item +--- + +Ordered lists that are the first sub-item of an unordered list item must have a preceding blank line if they don't start with `1.`. + +**Good** + +```markdown +- Unordered list item + + 5. First ordered list item +``` + +**Bad** + +```markdown +- Unordered list item + 5. First ordered list item +``` + +--- + +CommonMark ignores blank lines between ordered and unordered list items, and considers them part of a single list. These are rendered as a +_[loose](https://spec.commonmark.org/0.30/#loose)_ list. Each list item is enclosed in a paragraph tag and, therefore, has paragraph spacing and margins. +This makes the list look like there is extra spacing between each item. + +For example: + +```markdown +- First list item +- Second list item + +- A different list +``` + +CommonMark ignores the blank line and renders this as one list with paragraph spacing. + ### Superscripts / Subscripts CommonMark and GitLab Flavored Markdown don't support the Redcarpet superscript syntax ( `x^2` ). diff --git a/lib/api/internal/kubernetes.rb b/lib/api/internal/kubernetes.rb index f7c6e48e54f..cfec2287ea3 100644 --- a/lib/api/internal/kubernetes.rb +++ b/lib/api/internal/kubernetes.rb @@ -54,6 +54,10 @@ module API ::Clusters::AgentTokens::TrackUsageService.new(agent_token).execute end + + def agent_has_access_to_project?(project) + Guest.can?(:download_code, project) || agent.has_access_to?(project) + end end namespace 'internal' do @@ -79,6 +83,24 @@ module API default_branch: project.default_branch_or_main } end + + desc 'Gets project info' do + detail 'Retrieves project info (if authorized)' + end + route_setting :authentication, cluster_agent_token_allowed: true + get '/project_info', urgency: :low do + project = find_project(params[:id]) + + not_found! unless agent_has_access_to_project?(project) + + status 200 + { + project_id: project.id, + gitaly_info: gitaly_info(project), + gitaly_repository: gitaly_repository(project), + default_branch: project.default_branch_or_main + } + end end namespace 'kubernetes/agent_configuration', urgency: :low do diff --git a/lib/gitlab/background_migration/backfill_vulnerability_reads_cluster_agent.rb b/lib/gitlab/background_migration/backfill_vulnerability_reads_cluster_agent.rb new file mode 100644 index 00000000000..728b60f7a0e --- /dev/null +++ b/lib/gitlab/background_migration/backfill_vulnerability_reads_cluster_agent.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +module Gitlab + module BackgroundMigration + # Backfills the `vulnerability_reads.casted_cluster_agent_id` column + class BackfillVulnerabilityReadsClusterAgent < Gitlab::BackgroundMigration::BatchedMigrationJob + CLUSTER_AGENTS_JOIN = <<~SQL + INNER JOIN cluster_agents + ON CAST(vulnerability_reads.cluster_agent_id AS bigint) = cluster_agents.id AND + vulnerability_reads.project_id = cluster_agents.project_id + SQL + + RELATION = ->(relation) do + relation + .where(report_type: 7) + end + + def perform + each_sub_batch( + operation_name: :update_all, + batching_scope: RELATION + ) do |sub_batch| + sub_batch + .joins(CLUSTER_AGENTS_JOIN) + .update_all('casted_cluster_agent_id = CAST(vulnerability_reads.cluster_agent_id AS bigint)') + end + end + end + end +end diff --git a/lib/gitlab/background_migration/batching_strategies/backfill_vulnerability_reads_cluster_agent_batching_strategy.rb b/lib/gitlab/background_migration/batching_strategies/backfill_vulnerability_reads_cluster_agent_batching_strategy.rb new file mode 100644 index 00000000000..f0d015198dc --- /dev/null +++ b/lib/gitlab/background_migration/batching_strategies/backfill_vulnerability_reads_cluster_agent_batching_strategy.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +module Gitlab + module BackgroundMigration + module BatchingStrategies + # Batching class to use for back-filling vulnerability_read's casted_cluster_agent_id from cluster_agent_id. + # Batches will be scoped to records where the report_type belongs to cluster_image_scanning. + # + # If no more batches exist in the table, returns nil. + class BackfillVulnerabilityReadsClusterAgentBatchingStrategy < PrimaryKeyBatchingStrategy + CLUSTER_IMAGE_SCANNING_REPORT_TYPE = 7 + + def apply_additional_filters(relation, job_arguments: [], job_class: nil) + relation.where(report_type: CLUSTER_IMAGE_SCANNING_REPORT_TYPE) + end + end + end + end +end diff --git a/locale/gitlab.pot b/locale/gitlab.pot index a89e8b0f3a3..1e5e891074b 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -23477,7 +23477,7 @@ msgstr "" msgid "Linked epics" msgstr "" -msgid "Linked issues" +msgid "Linked items" msgstr "" msgid "LinkedIn" diff --git a/spec/frontend/issuable/related_issues/components/related_issues_block_spec.js b/spec/frontend/issuable/related_issues/components/related_issues_block_spec.js index 7a350df0ba6..6fbf13fb6c4 100644 --- a/spec/frontend/issuable/related_issues/components/related_issues_block_spec.js +++ b/spec/frontend/issuable/related_issues/components/related_issues_block_spec.js @@ -37,9 +37,9 @@ describe('RelatedIssuesBlock', () => { }); it.each` - issuableType | pathIdSeparator | titleText | helpLinkText | addButtonText - ${'issue'} | ${PathIdSeparator.Issue} | ${'Linked issues'} | ${'Read more about related issues'} | ${'Add a related issue'} - ${'epic'} | ${PathIdSeparator.Epic} | ${'Linked epics'} | ${'Read more about related epics'} | ${'Add a related epic'} + issuableType | pathIdSeparator | titleText | helpLinkText | addButtonText + ${'issue'} | ${PathIdSeparator.Issue} | ${'Linked items'} | ${'Read more about related issues'} | ${'Add a related issue'} + ${'epic'} | ${PathIdSeparator.Epic} | ${'Linked epics'} | ${'Read more about related epics'} | ${'Add a related epic'} `( 'displays "$titleText" in the header, "$helpLinkText" aria-label for help link, and "$addButtonText" aria-label for add button when issuableType is set to "$issuableType"', ({ issuableType, pathIdSeparator, titleText, helpLinkText, addButtonText }) => { diff --git a/spec/initializers/00_deprecations_spec.rb b/spec/initializers/00_deprecations_spec.rb new file mode 100644 index 00000000000..e52e64415af --- /dev/null +++ b/spec/initializers/00_deprecations_spec.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe '00_deprecations' do + where(:warning) do + [ + "ActiveModel::Errors#keys is deprecated and will be removed in Rails 6.2", + "Rendering actions with '.' in the name is deprecated:", + "default_hash is deprecated and will be removed from Rails 6.2" + ] + end + + with_them do + specify do + expect { ActiveSupport::Deprecation.warn(warning) } + .to raise_error(ActiveSupport::DeprecationException) + end + end +end diff --git a/spec/lib/gitlab/background_migration/backfill_vulnerability_reads_cluster_agent_spec.rb b/spec/lib/gitlab/background_migration/backfill_vulnerability_reads_cluster_agent_spec.rb new file mode 100644 index 00000000000..79699375a8d --- /dev/null +++ b/spec/lib/gitlab/background_migration/backfill_vulnerability_reads_cluster_agent_spec.rb @@ -0,0 +1,93 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::BackgroundMigration::BackfillVulnerabilityReadsClusterAgent, :migration, schema: 20220525221133 do # rubocop:disable Layout/LineLength + let(:migration) do + described_class.new(start_id: 1, end_id: 10, + batch_table: table_name, batch_column: batch_column, + sub_batch_size: sub_batch_size, pause_ms: pause_ms, + connection: ApplicationRecord.connection) + end + + let(:users_table) { table(:users) } + let(:vulnerability_reads_table) { table(:vulnerability_reads) } + let(:vulnerability_scanners_table) { table(:vulnerability_scanners) } + let(:vulnerabilities_table) { table(:vulnerabilities) } + let(:namespaces_table) { table(:namespaces) } + let(:projects_table) { table(:projects) } + let(:cluster_agents_table) { table(:cluster_agents) } + + let(:table_name) { 'vulnerability_reads' } + let(:batch_column) { :id } + let(:sub_batch_size) { 1_000 } + let(:pause_ms) { 0 } + + subject(:perform_migration) { migration.perform } + + before do + users_table.create!(id: 1, name: 'John Doe', email: 'test@example.com', projects_limit: 5) + + namespaces_table.create!(id: 1, name: 'Namespace 1', path: 'namespace-1') + namespaces_table.create!(id: 2, name: 'Namespace 2', path: 'namespace-2') + + projects_table.create!(id: 1, namespace_id: 1, name: 'Project 1', path: 'project-1', project_namespace_id: 1) + projects_table.create!(id: 2, namespace_id: 2, name: 'Project 2', path: 'project-2', project_namespace_id: 2) + + cluster_agents_table.create!(id: 1, name: 'Agent 1', project_id: 1) + cluster_agents_table.create!(id: 2, name: 'Agent 2', project_id: 2) + + vulnerability_scanners_table.create!(id: 1, project_id: 1, external_id: 'starboard', name: 'Starboard') + vulnerability_scanners_table.create!(id: 2, project_id: 2, external_id: 'starboard', name: 'Starboard') + + add_vulnerability_read!(1, project_id: 1, cluster_agent_id: 1, report_type: 7) + add_vulnerability_read!(3, project_id: 1, cluster_agent_id: 2, report_type: 7) + add_vulnerability_read!(5, project_id: 2, cluster_agent_id: 2, report_type: 5) + add_vulnerability_read!(7, project_id: 2, cluster_agent_id: 3, report_type: 7) + add_vulnerability_read!(9, project_id: 2, cluster_agent_id: 2, report_type: 7) + add_vulnerability_read!(10, project_id: 1, cluster_agent_id: 1, report_type: 7) + add_vulnerability_read!(11, project_id: 1, cluster_agent_id: 1, report_type: 7) + end + + it 'backfills `casted_cluster_agent_id` for the selected records', :aggregate_failures do + queries = ActiveRecord::QueryRecorder.new do + perform_migration + end + + expect(queries.count).to eq(3) + expect(vulnerability_reads_table.where.not(casted_cluster_agent_id: nil).count).to eq 3 + expect(vulnerability_reads_table.where.not(casted_cluster_agent_id: nil).pluck(:id)).to match_array([1, 9, 10]) + end + + it 'tracks timings of queries' do + expect(migration.batch_metrics.timings).to be_empty + + expect { perform_migration }.to change { migration.batch_metrics.timings } + end + + private + + def add_vulnerability_read!(id, project_id:, cluster_agent_id:, report_type:) + vulnerabilities_table.create!( + id: id, + project_id: project_id, + author_id: 1, + title: "Vulnerability #{id}", + severity: 5, + confidence: 5, + report_type: report_type + ) + + vulnerability_reads_table.create!( + id: id, + uuid: SecureRandom.uuid, + severity: 5, + state: 1, + vulnerability_id: id, + scanner_id: project_id, + cluster_agent_id: cluster_agent_id.to_s, + project_id: project_id, + report_type: report_type + ) + end +end diff --git a/spec/migrations/20220525221133_schedule_backfill_vulnerability_reads_cluster_agent_spec.rb b/spec/migrations/20220525221133_schedule_backfill_vulnerability_reads_cluster_agent_spec.rb new file mode 100644 index 00000000000..3f1a2d8c4b9 --- /dev/null +++ b/spec/migrations/20220525221133_schedule_backfill_vulnerability_reads_cluster_agent_spec.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe ScheduleBackfillVulnerabilityReadsClusterAgent do + let_it_be(:batched_migration) { described_class::MIGRATION_NAME } + + it 'schedules background jobs for each batch of vulnerability reads' do + reversible_migration do |migration| + migration.before -> { + expect(batched_migration).not_to have_scheduled_batched_migration + } + + migration.after -> { + expect(batched_migration).to have_scheduled_batched_migration( + table_name: :vulnerability_reads, + column_name: :id, + interval: described_class::DELAY_INTERVAL + ) + } + end + end +end diff --git a/spec/requests/api/internal/kubernetes_spec.rb b/spec/requests/api/internal/kubernetes_spec.rb index c0a979995c9..9dd098973d3 100644 --- a/spec/requests/api/internal/kubernetes_spec.rb +++ b/spec/requests/api/internal/kubernetes_spec.rb @@ -180,4 +180,95 @@ RSpec.describe API::Internal::Kubernetes do end end end + + describe 'GET /internal/kubernetes/project_info' do + def send_request(headers: {}, params: {}) + get api('/internal/kubernetes/project_info'), params: params, headers: headers.reverse_merge(jwt_auth_headers) + end + + include_examples 'authorization' + include_examples 'agent authentication' + + context 'an agent is found' do + let_it_be(:agent_token) { create(:cluster_agent_token) } + + shared_examples 'agent token tracking' + + context 'project is public' do + let(:project) { create(:project, :public) } + + it 'returns expected data', :aggregate_failures do + send_request(params: { id: project.id }, headers: { 'Authorization' => "Bearer #{agent_token.token}" }) + + expect(response).to have_gitlab_http_status(:success) + + expect(json_response).to match( + a_hash_including( + 'project_id' => project.id, + 'gitaly_info' => a_hash_including( + 'address' => match(/\.socket$/), + 'token' => 'secret', + 'features' => {} + ), + 'gitaly_repository' => a_hash_including( + 'storage_name' => project.repository_storage, + 'relative_path' => project.disk_path + '.git', + 'gl_repository' => "project-#{project.id}", + 'gl_project_path' => project.full_path + ), + 'default_branch' => project.default_branch_or_main + ) + ) + end + + context 'repository is for project members only' do + let(:project) { create(:project, :public, :repository_private) } + + it 'returns 404' do + send_request(params: { id: project.id }, headers: { 'Authorization' => "Bearer #{agent_token.token}" }) + + expect(response).to have_gitlab_http_status(:not_found) + end + end + end + + context 'project is private' do + let(:project) { create(:project, :private) } + + it 'returns 404' do + send_request(params: { id: project.id }, headers: { 'Authorization' => "Bearer #{agent_token.token}" }) + + expect(response).to have_gitlab_http_status(:not_found) + end + + context 'and agent belongs to project' do + let(:agent_token) { create(:cluster_agent_token, agent: create(:cluster_agent, project: project)) } + + it 'returns 200' do + send_request(params: { id: project.id }, headers: { 'Authorization' => "Bearer #{agent_token.token}" }) + + expect(response).to have_gitlab_http_status(:success) + end + end + end + + context 'project is internal' do + let(:project) { create(:project, :internal) } + + it 'returns 404' do + send_request(params: { id: project.id }, headers: { 'Authorization' => "Bearer #{agent_token.token}" }) + + expect(response).to have_gitlab_http_status(:not_found) + end + end + + context 'project does not exist' do + it 'returns 404' do + send_request(params: { id: non_existing_record_id }, headers: { 'Authorization' => "Bearer #{agent_token.token}" }) + + expect(response).to have_gitlab_http_status(:not_found) + end + end + end + end end