summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-06-09 21:08:21 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-06-09 21:08:21 +0000
commit64786982930713d095ccd3aebd812182a1879fed (patch)
tree542e79df02f79049d8a63b31388c7d1e3e3b9166
parent3d0474695407d24d49bb94f29a182739ee35e1f8 (diff)
downloadgitlab-ce-64786982930713d095ccd3aebd812182a1879fed.tar.gz
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--.rubocop.yml9
-rw-r--r--.rubocop_todo.yml521
-rw-r--r--app/assets/javascripts/alert_management/components/alert_management_list.vue4
-rw-r--r--app/assets/javascripts/alert_management/graphql/fragments/list_item.fragment.graphql8
-rw-r--r--app/assets/javascripts/clusters_list/components/clusters.vue141
-rw-r--r--app/controllers/repositories/git_http_controller.rb2
-rw-r--r--app/graphql/resolvers/alert_management/alerts/assignees_resolver.rb35
-rw-r--r--app/graphql/types/alert_management/alert_type.rb11
-rw-r--r--app/models/alert_management/alert_assignee.rb2
-rw-r--r--app/models/ci/pipeline.rb12
-rw-r--r--app/models/clusters/cluster.rb5
-rw-r--r--changelogs/unreleased/215668-settings-auto-fix.yml5
-rw-r--r--changelogs/unreleased/feature-show-memory-cpu-on-cluster-list.yml5
-rw-r--r--config/webpack.config.js9
-rw-r--r--db/migrate/20200604143628_create_project_security_settings.rb27
-rw-r--r--db/structure.sql28
-rw-r--r--doc/api/graphql/reference/gitlab_schema.graphql22
-rw-r--r--doc/api/graphql/reference/gitlab_schema.json55
-rw-r--r--doc/api/graphql/reference/index.md1
-rw-r--r--doc/ci/environments/incremental_rollouts.md2
-rw-r--r--doc/development/telemetry/usage_ping.md6
-rw-r--r--doc/user/application_security/dependency_scanning/index.md32
-rw-r--r--doc/user/packages/container_registry/index.md5
-rw-r--r--doc/user/project/pages/custom_domains_ssl_tls_certification/index.md3
-rw-r--r--lib/gitlab/git_access.rb32
-rw-r--r--lib/gitlab/git_access_project.rb44
-rw-r--r--lib/gitlab/git_access_snippet.rb5
-rw-r--r--lib/gitlab/gl_repository.rb2
-rw-r--r--lib/gitlab/graphql/loaders/alert_management/alerts/assignees_loader.rb52
-rw-r--r--lib/gitlab/import_export/project/import_export.yml1
-rw-r--r--locale/gitlab.pot18
-rw-r--r--spec/frontend/alert_management/components/alert_management_list_spec.js3
-rw-r--r--spec/frontend/alert_management/mocks/alerts.json64
-rw-r--r--spec/frontend/clusters_list/components/clusters_spec.js62
-rw-r--r--spec/frontend/clusters_list/mock_data.js28
-rw-r--r--spec/graphql/resolvers/alert_management/alerts/assignees_resolver_spec.rb32
-rw-r--r--spec/lib/gitlab/ci/yaml_processor_spec.rb2
-rw-r--r--spec/lib/gitlab/git_access_project_spec.rb166
-rw-r--r--spec/lib/gitlab/git_access_spec.rb136
-rw-r--r--spec/lib/gitlab/graphql/loaders/alert_management/alerts/assignees_loader_spec.rb44
-rw-r--r--spec/lib/gitlab/import_export/all_models.yml1
-rw-r--r--spec/lib/gitlab/import_export/import_test_coverage_spec.rb1
-rw-r--r--spec/lib/gitlab/import_export/safe_model_attributes.yml8
-rw-r--r--spec/models/alert_management/alert_assignee_spec.rb26
-rw-r--r--spec/models/ci/pipeline_spec.rb24
-rw-r--r--spec/models/clusters/cluster_spec.rb12
-rw-r--r--spec/requests/api/graphql/project/alert_management/alert/assignees_spec.rb85
-rw-r--r--spec/requests/api/graphql/project/alert_management/alerts_spec.rb15
48 files changed, 1216 insertions, 597 deletions
diff --git a/.rubocop.yml b/.rubocop.yml
index f9e92340afa..3b4a7a9369d 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -447,3 +447,12 @@ Rails/TimeZone:
- 'spec/models/**/*'
- 'ee/app/models/**/*'
- 'ee/spec/models/**/*'
+
+# WIP: See https://gitlab.com/gitlab-org/gitlab/-/issues/220040
+Rails/SaveBang:
+ Enabled: true
+ Include:
+ - 'spec/**/*.rb'
+ - 'ee/spec/**/*.rb'
+ - 'qa/spec/**/*.rb'
+ - 'qa/qa/specs/**/*.rb'
diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml
index a4c56feda27..9e3a54fa7e9 100644
--- a/.rubocop_todo.yml
+++ b/.rubocop_todo.yml
@@ -768,3 +768,524 @@ Style/StringLiteralsInInterpolation:
# IgnoredMethods: respond_to, define_method
Style/SymbolProc:
Enabled: false
+
+# Offense count: 1478
+# Cop supports --auto-correct.
+# Configuration parameters: AllowImplicitReturn, AllowedReceivers.
+Rails/SaveBang:
+ Exclude:
+ - 'ee/spec/controllers/groups/epic_issues_controller_spec.rb'
+ - 'ee/spec/controllers/groups/epic_links_controller_spec.rb'
+ - 'ee/spec/controllers/groups/epics_controller_spec.rb'
+ - 'ee/spec/controllers/groups/roadmap_controller_spec.rb'
+ - 'ee/spec/controllers/projects/environments_controller_spec.rb'
+ - 'ee/spec/controllers/projects/issues_controller_spec.rb'
+ - 'ee/spec/controllers/projects/merge_requests/creations_controller_spec.rb'
+ - 'ee/spec/controllers/projects/merge_requests_controller_spec.rb'
+ - 'ee/spec/controllers/projects/service_desk_controller_spec.rb'
+ - 'ee/spec/controllers/projects/subscriptions_controller_spec.rb'
+ - 'ee/spec/controllers/projects/vulnerability_feedback_controller_spec.rb'
+ - 'ee/spec/controllers/subscriptions_controller_spec.rb'
+ - 'ee/spec/factories/merge_requests.rb'
+ - 'ee/spec/features/admin/geo/admin_geo_nodes_spec.rb'
+ - 'ee/spec/features/boards/scoped_issue_board_spec.rb'
+ - 'ee/spec/features/ci_shared_runner_warnings_spec.rb'
+ - 'ee/spec/features/dashboards/operations_spec.rb'
+ - 'ee/spec/features/issues/gfm_autocomplete_ee_spec.rb'
+ - 'ee/spec/features/merge_request/user_approves_spec.rb'
+ - 'ee/spec/features/merge_requests/user_views_all_merge_requests_spec.rb'
+ - 'ee/spec/features/projects/members/invite_group_and_members_spec.rb'
+ - 'ee/spec/features/projects/merge_requests/user_approves_merge_request_spec.rb'
+ - 'ee/spec/features/projects/new_project_spec.rb'
+ - 'ee/spec/features/projects/settings/user_manages_approval_settings_spec.rb'
+ - 'ee/spec/features/projects/settings/user_manages_members_spec.rb'
+ - 'ee/spec/features/search/elastic/global_search_spec.rb'
+ - 'ee/spec/finders/epics_finder_spec.rb'
+ - 'ee/spec/frontend/fixtures/analytics.rb'
+ - 'ee/spec/helpers/application_helper_spec.rb'
+ - 'ee/spec/helpers/ee/issues_helper_spec.rb'
+ - 'ee/spec/initializers/fog_google_https_private_urls_spec.rb'
+ - 'ee/spec/lib/analytics/merge_request_metrics_calculator_spec.rb'
+ - 'ee/spec/lib/ee/gitlab/auth/ldap/sync/group_spec.rb'
+ - 'ee/spec/lib/ee/gitlab/background_migration/migrate_approver_to_approval_rules_spec.rb'
+ - 'ee/spec/lib/ee/gitlab/background_migration/move_epic_issues_after_epics_spec.rb'
+ - 'ee/spec/lib/ee/gitlab/background_migration/populate_any_approval_rule_for_merge_requests_spec.rb'
+ - 'ee/spec/lib/ee/gitlab/background_migration/populate_any_approval_rule_for_projects_spec.rb'
+ - 'ee/spec/lib/ee/gitlab/checks/push_rules/commit_check_spec.rb'
+ - 'ee/spec/lib/ee/gitlab/ci/pipeline/quota/activity_spec.rb'
+ - 'ee/spec/lib/gitlab/auth/ldap/access_spec.rb'
+ - 'ee/spec/lib/gitlab/auth/o_auth/user_spec.rb'
+ - 'ee/spec/lib/gitlab/auth/saml/user_spec.rb'
+ - 'ee/spec/lib/gitlab/elastic/search_results_spec.rb'
+ - 'ee/spec/lib/gitlab/email/handler/ee/service_desk_handler_spec.rb'
+ - 'ee/spec/lib/gitlab/geo/jwt_request_decoder_spec.rb'
+ - 'ee/spec/lib/gitlab/geo/oauth/session_spec.rb'
+ - 'ee/spec/lib/gitlab/geo_spec.rb'
+ - 'ee/spec/lib/gitlab/git_access_spec.rb'
+ - 'ee/spec/mailers/notify_spec.rb'
+ - 'ee/spec/migrations/geo/migrate_ci_job_artifacts_to_separate_registry_spec.rb'
+ - 'ee/spec/migrations/geo/migrate_lfs_objects_to_separate_registry_spec.rb'
+ - 'ee/spec/migrations/schedule_project_any_approval_rule_migration_spec.rb'
+ - 'ee/spec/models/application_setting_spec.rb'
+ - 'ee/spec/models/approval_merge_request_rule_spec.rb'
+ - 'ee/spec/models/approval_state_spec.rb'
+ - 'ee/spec/models/burndown_spec.rb'
+ - 'ee/spec/models/ci/build_spec.rb'
+ - 'ee/spec/models/ci/pipeline_spec.rb'
+ - 'ee/spec/models/ci/subscriptions/project_spec.rb'
+ - 'ee/spec/models/concerns/deprecated_approvals_before_merge_spec.rb'
+ - 'ee/spec/models/concerns/elastic/note_spec.rb'
+ - 'ee/spec/models/ee/protected_branch_spec.rb'
+ - 'ee/spec/models/ee/protected_ref_access_spec.rb'
+ - 'ee/spec/models/ee/protected_ref_spec.rb'
+ - 'ee/spec/models/epic_spec.rb'
+ - 'ee/spec/models/geo/project_registry_spec.rb'
+ - 'ee/spec/models/geo_node_spec.rb'
+ - 'ee/spec/models/geo_node_status_spec.rb'
+ - 'ee/spec/models/group_spec.rb'
+ - 'ee/spec/models/issue_spec.rb'
+ - 'ee/spec/models/label_note_spec.rb'
+ - 'ee/spec/models/license_spec.rb'
+ - 'ee/spec/models/merge_request_spec.rb'
+ - 'ee/spec/models/operations/feature_flag_scope_spec.rb'
+ - 'ee/spec/models/operations/feature_flag_spec.rb'
+ - 'ee/spec/models/operations/feature_flags/strategy_spec.rb'
+ - 'ee/spec/models/operations/feature_flags/user_list_spec.rb'
+ - 'ee/spec/models/project_services/github_service_spec.rb'
+ - 'ee/spec/models/project_services/jenkins_service_spec.rb'
+ - 'ee/spec/models/project_spec.rb'
+ - 'ee/spec/models/scim_identity_spec.rb'
+ - 'ee/spec/models/scim_oauth_access_token_spec.rb'
+ - 'ee/spec/models/user_preference_spec.rb'
+ - 'ee/spec/models/user_spec.rb'
+ - 'ee/spec/models/visible_approvable_spec.rb'
+ - 'ee/spec/models/vulnerabilities/feedback_spec.rb'
+ - 'ee/spec/models/vulnerabilities/issue_link_spec.rb'
+ - 'ee/spec/policies/protected_branch_policy_spec.rb'
+ - 'ee/spec/presenters/audit_event_presenter_spec.rb'
+ - 'ee/spec/presenters/epic_presenter_spec.rb'
+ - 'ee/spec/presenters/packages/conan/package_presenter_spec.rb'
+ - 'ee/spec/requests/api/boards_spec.rb'
+ - 'ee/spec/requests/api/epic_issues_spec.rb'
+ - 'ee/spec/requests/api/epic_links_spec.rb'
+ - 'ee/spec/requests/api/epics_spec.rb'
+ - 'ee/spec/requests/api/geo_nodes_spec.rb'
+ - 'ee/spec/requests/api/geo_spec.rb'
+ - 'ee/spec/requests/api/graphql/group/epics_spec.rb'
+ - 'ee/spec/requests/api/graphql/mutations/epic_tree/reorder_spec.rb'
+ - 'ee/spec/requests/api/groups_spec.rb'
+ - 'ee/spec/requests/api/issues_spec.rb'
+ - 'ee/spec/requests/api/ldap_group_links_spec.rb'
+ - 'ee/spec/requests/api/maven_packages_spec.rb'
+ - 'ee/spec/requests/api/merge_request_approval_rules_spec.rb'
+ - 'ee/spec/requests/api/merge_request_approvals_spec.rb'
+ - 'ee/spec/requests/api/merge_requests_spec.rb'
+ - 'ee/spec/requests/api/project_approvals_spec.rb'
+ - 'ee/spec/requests/api/projects_spec.rb'
+ - 'ee/spec/requests/api/protected_branches_spec.rb'
+ - 'ee/spec/requests/api/scim_spec.rb'
+ - 'ee/spec/requests/api/todos_spec.rb'
+ - 'ee/spec/services/approval_rules/finalize_service_spec.rb'
+ - 'ee/spec/services/ci/register_job_service_spec.rb'
+ - 'ee/spec/services/ee/boards/issues/create_service_spec.rb'
+ - 'ee/spec/services/ee/issuable/clone/attributes_rewriter_spec.rb'
+ - 'ee/spec/services/ee/issuable/common_system_notes_service_spec.rb'
+ - 'ee/spec/services/ee/issues/update_service_spec.rb'
+ - 'ee/spec/services/ee/merge_requests/refresh_service_spec.rb'
+ - 'ee/spec/services/ee/merge_requests/update_service_spec.rb'
+ - 'ee/spec/services/ee/notes/quick_actions_service_spec.rb'
+ - 'ee/spec/services/ee/notification_service_spec.rb'
+ - 'ee/spec/services/ee/resource_events/change_weight_service_spec.rb'
+ - 'ee/spec/services/elastic/index_record_service_spec.rb'
+ - 'ee/spec/services/epic_links/create_service_spec.rb'
+ - 'ee/spec/services/epics/issue_promote_service_spec.rb'
+ - 'ee/spec/services/epics/tree_reorder_service_spec.rb'
+ - 'ee/spec/services/epics/update_dates_service_spec.rb'
+ - 'ee/spec/services/epics/update_service_spec.rb'
+ - 'ee/spec/services/geo/blob_verification_secondary_service_spec.rb'
+ - 'ee/spec/services/geo/metrics_update_service_spec.rb'
+ - 'ee/spec/services/geo/registry_consistency_service_spec.rb'
+ - 'ee/spec/services/geo/repository_verification_secondary_service_spec.rb'
+ - 'ee/spec/services/groups/autocomplete_service_spec.rb'
+ - 'ee/spec/services/ldap_group_reset_service_spec.rb'
+ - 'ee/spec/services/lfs/unlock_file_service_spec.rb'
+ - 'ee/spec/services/merge_requests/approval_service_spec.rb'
+ - 'ee/spec/services/merge_requests/remove_approval_service_spec.rb'
+ - 'ee/spec/services/merge_trains/refresh_merge_request_service_spec.rb'
+ - 'ee/spec/services/projects/after_rename_service_spec.rb'
+ - 'ee/spec/services/projects/update_service_spec.rb'
+ - 'ee/spec/services/quick_actions/interpret_service_spec.rb'
+ - 'ee/spec/services/slash_commands/global_slack_handler_spec.rb'
+ - 'ee/spec/services/start_pull_mirroring_service_spec.rb'
+ - 'ee/spec/services/status_page/trigger_publish_service_spec.rb'
+ - 'ee/spec/services/todo_service_spec.rb'
+ - 'ee/spec/services/update_build_minutes_service_spec.rb'
+ - 'ee/spec/support/shared_examples/lib/analytics/common_merge_request_metrics_refresh_shared_examples.rb'
+ - 'ee/spec/support/shared_examples/models/concerns/replicator_shared_examples.rb'
+ - 'ee/spec/support/shared_examples/models/member_shared_examples.rb'
+ - 'ee/spec/support/shared_examples/models/mentionable_shared_examples.rb'
+ - 'ee/spec/support/shared_examples/policies/protected_environments_shared_examples.rb'
+ - 'ee/spec/support/shared_examples/requests/api/project_approval_rules_api_shared_examples.rb'
+ - 'ee/spec/support/shared_examples/services/issue_epic_shared_examples.rb'
+ - 'ee/spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb'
+ - 'ee/spec/workers/adjourned_project_deletion_worker_spec.rb'
+ - 'ee/spec/workers/create_github_webhook_worker_spec.rb'
+ - 'ee/spec/workers/elastic_indexer_worker_spec.rb'
+ - 'ee/spec/workers/geo/container_repository_sync_dispatch_worker_spec.rb'
+ - 'ee/spec/workers/geo/file_download_dispatch_worker_spec.rb'
+ - 'ee/spec/workers/geo/repository_shard_sync_worker_spec.rb'
+ - 'ee/spec/workers/repository_import_worker_spec.rb'
+ - 'ee/spec/workers/update_all_mirrors_worker_spec.rb'
+ - 'qa/qa/specs/features/browser_ui/3_create/repository/push_mirroring_over_http_spec.rb'
+ - 'qa/qa/specs/features/ee/browser_ui/3_create/repository/pull_mirroring_over_http_spec.rb'
+ - 'spec/controllers/abuse_reports_controller_spec.rb'
+ - 'spec/controllers/admin/impersonations_controller_spec.rb'
+ - 'spec/controllers/admin/runners_controller_spec.rb'
+ - 'spec/controllers/boards/issues_controller_spec.rb'
+ - 'spec/controllers/groups/runners_controller_spec.rb'
+ - 'spec/controllers/oauth/authorizations_controller_spec.rb'
+ - 'spec/controllers/omniauth_callbacks_controller_spec.rb'
+ - 'spec/controllers/profiles/emails_controller_spec.rb'
+ - 'spec/controllers/profiles/notifications_controller_spec.rb'
+ - 'spec/controllers/projects/artifacts_controller_spec.rb'
+ - 'spec/controllers/projects/cycle_analytics_controller_spec.rb'
+ - 'spec/controllers/projects/issues_controller_spec.rb'
+ - 'spec/controllers/projects/labels_controller_spec.rb'
+ - 'spec/controllers/projects/merge_requests_controller_spec.rb'
+ - 'spec/controllers/projects/milestones_controller_spec.rb'
+ - 'spec/controllers/projects/notes_controller_spec.rb'
+ - 'spec/controllers/projects/pipelines_controller_spec.rb'
+ - 'spec/controllers/projects/runners_controller_spec.rb'
+ - 'spec/controllers/projects_controller_spec.rb'
+ - 'spec/factories/ci/pipelines.rb'
+ - 'spec/factories/design_management/designs.rb'
+ - 'spec/factories/design_management/versions.rb'
+ - 'spec/factories/labels.rb'
+ - 'spec/factories/projects.rb'
+ - 'spec/features/admin/admin_mode/login_spec.rb'
+ - 'spec/features/admin/admin_runners_spec.rb'
+ - 'spec/features/admin/admin_users_impersonation_tokens_spec.rb'
+ - 'spec/features/admin/admin_users_spec.rb'
+ - 'spec/features/boards/sidebar_spec.rb'
+ - 'spec/features/calendar_spec.rb'
+ - 'spec/features/commits_spec.rb'
+ - 'spec/features/dashboard/datetime_on_tooltips_spec.rb'
+ - 'spec/features/dashboard/issuables_counter_spec.rb'
+ - 'spec/features/dashboard/project_member_activity_index_spec.rb'
+ - 'spec/features/dashboard/projects_spec.rb'
+ - 'spec/features/error_tracking/user_sees_error_index_spec.rb'
+ - 'spec/features/groups/members/request_access_spec.rb'
+ - 'spec/features/issues/bulk_assignment_labels_spec.rb'
+ - 'spec/features/issues/gfm_autocomplete_spec.rb'
+ - 'spec/features/issues/issue_sidebar_spec.rb'
+ - 'spec/features/issues/note_polling_spec.rb'
+ - 'spec/features/issues/user_creates_branch_and_merge_request_spec.rb'
+ - 'spec/features/issues/user_creates_confidential_merge_request_spec.rb'
+ - 'spec/features/issues/user_edits_issue_spec.rb'
+ - 'spec/features/issues/user_filters_issues_spec.rb'
+ - 'spec/features/issues/user_sees_live_update_spec.rb'
+ - 'spec/features/issues/user_sorts_issues_spec.rb'
+ - 'spec/features/merge_request/user_merges_when_pipeline_succeeds_spec.rb'
+ - 'spec/features/merge_request/user_posts_diff_notes_spec.rb'
+ - 'spec/features/merge_request/user_resolves_diff_notes_and_discussions_resolve_spec.rb'
+ - 'spec/features/merge_request/user_sees_cherry_pick_modal_spec.rb'
+ - 'spec/features/merge_request/user_sees_merge_widget_spec.rb'
+ - 'spec/features/merge_requests/user_mass_updates_spec.rb'
+ - 'spec/features/profiles/emails_spec.rb'
+ - 'spec/features/profiles/password_spec.rb'
+ - 'spec/features/profiles/personal_access_tokens_spec.rb'
+ - 'spec/features/projects/features_visibility_spec.rb'
+ - 'spec/features/projects/jobs_spec.rb'
+ - 'spec/features/projects/members/user_requests_access_spec.rb'
+ - 'spec/features/projects/pages_lets_encrypt_spec.rb'
+ - 'spec/features/projects/pages_spec.rb'
+ - 'spec/features/projects/remote_mirror_spec.rb'
+ - 'spec/features/projects/services/user_activates_slack_notifications_spec.rb'
+ - 'spec/features/projects/settings/access_tokens_spec.rb'
+ - 'spec/features/projects/show/user_sees_deletion_failure_message_spec.rb'
+ - 'spec/features/projects/user_sees_sidebar_spec.rb'
+ - 'spec/features/projects/wiki/user_updates_wiki_page_spec.rb'
+ - 'spec/features/projects/wiki/users_views_asciidoc_page_with_includes_spec.rb'
+ - 'spec/features/security/project/private_access_spec.rb'
+ - 'spec/features/users/login_spec.rb'
+ - 'spec/features/users/show_spec.rb'
+ - 'spec/finders/autocomplete/move_to_project_finder_spec.rb'
+ - 'spec/finders/group_descendants_finder_spec.rb'
+ - 'spec/finders/issues_finder_spec.rb'
+ - 'spec/finders/merge_requests_finder_spec.rb'
+ - 'spec/finders/projects_finder_spec.rb'
+ - 'spec/finders/uploader_finder_spec.rb'
+ - 'spec/frontend/fixtures/issues.rb'
+ - 'spec/frontend/fixtures/merge_requests.rb'
+ - 'spec/graphql/mutations/merge_requests/set_locked_spec.rb'
+ - 'spec/graphql/mutations/merge_requests/set_wip_spec.rb'
+ - 'spec/graphql/resolvers/boards_resolver_spec.rb'
+ - 'spec/helpers/appearances_helper_spec.rb'
+ - 'spec/helpers/profiles_helper_spec.rb'
+ - 'spec/helpers/projects/alert_management_helper_spec.rb'
+ - 'spec/helpers/projects_helper_spec.rb'
+ - 'spec/helpers/visibility_level_helper_spec.rb'
+ - 'spec/initializers/active_record_locking_spec.rb'
+ - 'spec/initializers/fog_google_https_private_urls_spec.rb'
+ - 'spec/lib/after_commit_queue_spec.rb'
+ - 'spec/lib/backup/manager_spec.rb'
+ - 'spec/lib/banzai/reference_parser/external_issue_parser_spec.rb'
+ - 'spec/lib/gitlab/analytics/cycle_analytics/records_fetcher_spec.rb'
+ - 'spec/lib/gitlab/auth/ldap/user_spec.rb'
+ - 'spec/lib/gitlab/auth/o_auth/user_spec.rb'
+ - 'spec/lib/gitlab/auth/saml/user_spec.rb'
+ - 'spec/lib/gitlab/auth_spec.rb'
+ - 'spec/lib/gitlab/background_migration/backfill_deployment_clusters_from_deployments_spec.rb'
+ - 'spec/lib/gitlab/background_migration/backfill_project_repositories_spec.rb'
+ - 'spec/lib/gitlab/background_migration/backfill_project_settings_spec.rb'
+ - 'spec/lib/gitlab/background_migration/backfill_push_rules_id_in_projects_spec.rb'
+ - 'spec/lib/gitlab/background_migration/digest_column_spec.rb'
+ - 'spec/lib/gitlab/background_migration/encrypt_columns_spec.rb'
+ - 'spec/lib/gitlab/background_migration/fix_cross_project_label_links_spec.rb'
+ - 'spec/lib/gitlab/background_migration/fix_projects_without_prometheus_service_spec.rb'
+ - 'spec/lib/gitlab/background_migration/fix_user_namespace_names_spec.rb'
+ - 'spec/lib/gitlab/background_migration/fix_user_project_route_names_spec.rb'
+ - 'spec/lib/gitlab/background_migration/legacy_upload_mover_spec.rb'
+ - 'spec/lib/gitlab/background_migration/legacy_uploads_migrator_spec.rb'
+ - 'spec/lib/gitlab/background_migration/link_lfs_objects_projects_spec.rb'
+ - 'spec/lib/gitlab/background_migration/migrate_issue_trackers_sensitive_data_spec.rb'
+ - 'spec/lib/gitlab/background_migration/migrate_stage_index_spec.rb'
+ - 'spec/lib/gitlab/background_migration/migrate_users_bio_to_user_details_spec.rb'
+ - 'spec/lib/gitlab/background_migration/populate_canonical_emails_spec.rb'
+ - 'spec/lib/gitlab/background_migration/populate_merge_request_assignees_table_spec.rb'
+ - 'spec/lib/gitlab/background_migration/populate_user_highest_roles_table_spec.rb'
+ - 'spec/lib/gitlab/background_migration/recalculate_project_authorizations_spec.rb'
+ - 'spec/lib/gitlab/background_migration/remove_restricted_todos_spec.rb'
+ - 'spec/lib/gitlab/background_migration/set_confidential_note_events_on_services_spec.rb'
+ - 'spec/lib/gitlab/background_migration/set_confidential_note_events_on_webhooks_spec.rb'
+ - 'spec/lib/gitlab/bitbucket_server_import/importer_spec.rb'
+ - 'spec/lib/gitlab/ci/ansi2json/style_spec.rb'
+ - 'spec/lib/gitlab/cycle_analytics/base_event_fetcher_spec.rb'
+ - 'spec/lib/gitlab/cycle_analytics/events_spec.rb'
+ - 'spec/lib/gitlab/database/custom_structure_spec.rb'
+ - 'spec/lib/gitlab/database/partitioning_migration_helpers/table_management_helpers_spec.rb'
+ - 'spec/lib/gitlab/database_importers/self_monitoring/project/create_service_spec.rb'
+ - 'spec/lib/gitlab/git/remote_mirror_spec.rb'
+ - 'spec/lib/gitlab/git_access_spec.rb'
+ - 'spec/lib/gitlab/gitaly_client/repository_service_spec.rb'
+ - 'spec/lib/gitlab/import_export/avatar_saver_spec.rb'
+ - 'spec/lib/gitlab/import_export/design_repo_restorer_spec.rb'
+ - 'spec/lib/gitlab/import_export/fast_hash_serializer_spec.rb'
+ - 'spec/lib/gitlab/import_export/fork_spec.rb'
+ - 'spec/lib/gitlab/import_export/group/legacy_tree_saver_spec.rb'
+ - 'spec/lib/gitlab/import_export/importer_spec.rb'
+ - 'spec/lib/gitlab/import_export/lfs_restorer_spec.rb'
+ - 'spec/lib/gitlab/import_export/lfs_saver_spec.rb'
+ - 'spec/lib/gitlab/import_export/members_mapper_spec.rb'
+ - 'spec/lib/gitlab/import_export/project/tree_restorer_spec.rb'
+ - 'spec/lib/gitlab/import_export/project/tree_saver_spec.rb'
+ - 'spec/lib/gitlab/import_export/repo_restorer_spec.rb'
+ - 'spec/lib/gitlab/import_export/saver_spec.rb'
+ - 'spec/lib/gitlab/import_export/snippet_repo_saver_spec.rb'
+ - 'spec/lib/gitlab/import_export/snippets_repo_restorer_spec.rb'
+ - 'spec/lib/gitlab/import_export/snippets_repo_saver_spec.rb'
+ - 'spec/lib/gitlab/import_export/uploads_manager_spec.rb'
+ - 'spec/lib/gitlab/import_export/uploads_saver_spec.rb'
+ - 'spec/lib/gitlab/import_export/wiki_restorer_spec.rb'
+ - 'spec/lib/gitlab/lets_encrypt/client_spec.rb'
+ - 'spec/lib/gitlab/markdown_cache/active_record/extension_spec.rb'
+ - 'spec/lib/gitlab/markdown_cache/redis/store_spec.rb'
+ - 'spec/lib/gitlab/shard_health_cache_spec.rb'
+ - 'spec/mailers/notify_spec.rb'
+ - 'spec/migrations/20200122123016_backfill_project_settings_spec.rb'
+ - 'spec/migrations/20200123155929_remove_invalid_jira_data_spec.rb'
+ - 'spec/migrations/20200127090233_remove_invalid_issue_tracker_data_spec.rb'
+ - 'spec/migrations/20200406102120_backfill_deployment_clusters_from_deployments_spec.rb'
+ - 'spec/migrations/add_unique_constraint_to_approvals_user_id_and_merge_request_id_spec.rb'
+ - 'spec/migrations/backfill_and_add_not_null_constraint_to_released_at_column_on_releases_table_spec.rb'
+ - 'spec/migrations/backfill_releases_table_updated_at_and_add_not_null_constraints_to_timestamps_spec.rb'
+ - 'spec/migrations/encrypt_plaintext_attributes_on_application_settings_spec.rb'
+ - 'spec/migrations/fill_file_store_lfs_objects_spec.rb'
+ - 'spec/migrations/fill_store_uploads_spec.rb'
+ - 'spec/migrations/fix_null_type_labels_spec.rb'
+ - 'spec/migrations/fix_pool_repository_source_project_id_spec.rb'
+ - 'spec/migrations/fix_wrong_pages_access_level_spec.rb'
+ - 'spec/migrations/insert_project_hooks_plan_limits_spec.rb'
+ - 'spec/migrations/migrate_auto_dev_ops_domain_to_cluster_domain_spec.rb'
+ - 'spec/migrations/schedule_link_lfs_objects_projects_spec.rb'
+ - 'spec/models/appearance_spec.rb'
+ - 'spec/models/application_setting_spec.rb'
+ - 'spec/models/ci/build_spec.rb'
+ - 'spec/models/ci/instance_variable_spec.rb'
+ - 'spec/models/ci/pipeline_spec.rb'
+ - 'spec/models/ci/runner_spec.rb'
+ - 'spec/models/clusters/applications/helm_spec.rb'
+ - 'spec/models/concerns/avatarable_spec.rb'
+ - 'spec/models/concerns/bulk_insertable_associations_spec.rb'
+ - 'spec/models/concerns/cache_markdown_field_spec.rb'
+ - 'spec/models/concerns/featurable_spec.rb'
+ - 'spec/models/concerns/issuable_spec.rb'
+ - 'spec/models/concerns/mentionable_spec.rb'
+ - 'spec/models/concerns/milestoneable_spec.rb'
+ - 'spec/models/concerns/routable_spec.rb'
+ - 'spec/models/concerns/subscribable_spec.rb'
+ - 'spec/models/concerns/token_authenticatable_spec.rb'
+ - 'spec/models/container_repository_spec.rb'
+ - 'spec/models/cycle_analytics/issue_spec.rb'
+ - 'spec/models/cycle_analytics/plan_spec.rb'
+ - 'spec/models/deploy_keys_project_spec.rb'
+ - 'spec/models/deploy_token_spec.rb'
+ - 'spec/models/deployment_spec.rb'
+ - 'spec/models/design_management/version_spec.rb'
+ - 'spec/models/diff_note_spec.rb'
+ - 'spec/models/email_spec.rb'
+ - 'spec/models/environment_spec.rb'
+ - 'spec/models/event_spec.rb'
+ - 'spec/models/fork_network_spec.rb'
+ - 'spec/models/generic_commit_status_spec.rb'
+ - 'spec/models/grafana_integration_spec.rb'
+ - 'spec/models/group_spec.rb'
+ - 'spec/models/hooks/system_hook_spec.rb'
+ - 'spec/models/hooks/web_hook_spec.rb'
+ - 'spec/models/identity_spec.rb'
+ - 'spec/models/issue_spec.rb'
+ - 'spec/models/key_spec.rb'
+ - 'spec/models/lfs_objects_project_spec.rb'
+ - 'spec/models/member_spec.rb'
+ - 'spec/models/members/group_member_spec.rb'
+ - 'spec/models/members/project_member_spec.rb'
+ - 'spec/models/merge_request_spec.rb'
+ - 'spec/models/milestone_spec.rb'
+ - 'spec/models/namespace_spec.rb'
+ - 'spec/models/note_spec.rb'
+ - 'spec/models/notification_setting_spec.rb'
+ - 'spec/models/pages_domain_spec.rb'
+ - 'spec/models/project_services/bamboo_service_spec.rb'
+ - 'spec/models/project_services/jira_service_spec.rb'
+ - 'spec/models/project_services/pipelines_email_service_spec.rb'
+ - 'spec/models/project_services/teamcity_service_spec.rb'
+ - 'spec/models/project_spec.rb'
+ - 'spec/models/project_team_spec.rb'
+ - 'spec/models/release_spec.rb'
+ - 'spec/models/remote_mirror_spec.rb'
+ - 'spec/models/resource_milestone_event_spec.rb'
+ - 'spec/models/route_spec.rb'
+ - 'spec/models/sentry_issue_spec.rb'
+ - 'spec/models/service_spec.rb'
+ - 'spec/models/snippet_spec.rb'
+ - 'spec/models/upload_spec.rb'
+ - 'spec/models/user_preference_spec.rb'
+ - 'spec/models/user_spec.rb'
+ - 'spec/models/wiki_page/meta_spec.rb'
+ - 'spec/models/wiki_page_spec.rb'
+ - 'spec/policies/ci/build_policy_spec.rb'
+ - 'spec/policies/ci/pipeline_policy_spec.rb'
+ - 'spec/policies/ci/pipeline_schedule_policy_spec.rb'
+ - 'spec/policies/merge_request_policy_spec.rb'
+ - 'spec/policies/project_policy_spec.rb'
+ - 'spec/requests/api/boards_spec.rb'
+ - 'spec/requests/api/deployments_spec.rb'
+ - 'spec/requests/api/environments_spec.rb'
+ - 'spec/requests/api/graphql/mutations/merge_requests/set_labels_spec.rb'
+ - 'spec/requests/api/graphql/user_query_spec.rb'
+ - 'spec/requests/api/graphql_spec.rb'
+ - 'spec/requests/api/group_milestones_spec.rb'
+ - 'spec/requests/api/internal/base_spec.rb'
+ - 'spec/requests/api/issues/get_group_issues_spec.rb'
+ - 'spec/requests/api/jobs_spec.rb'
+ - 'spec/requests/api/labels_spec.rb'
+ - 'spec/requests/api/members_spec.rb'
+ - 'spec/requests/api/merge_request_diffs_spec.rb'
+ - 'spec/requests/api/merge_requests_spec.rb'
+ - 'spec/requests/api/pipeline_schedules_spec.rb'
+ - 'spec/requests/api/project_import_spec.rb'
+ - 'spec/requests/api/projects_spec.rb'
+ - 'spec/requests/api/runners_spec.rb'
+ - 'spec/requests/api/snippets_spec.rb'
+ - 'spec/requests/git_http_spec.rb'
+ - 'spec/requests/profiles/notifications_controller_spec.rb'
+ - 'spec/requests/projects/cycle_analytics_events_spec.rb'
+ - 'spec/serializers/environment_status_entity_spec.rb'
+ - 'spec/serializers/merge_request_poll_widget_entity_spec.rb'
+ - 'spec/serializers/merge_request_widget_entity_spec.rb'
+ - 'spec/services/ci/create_pipeline_service_spec.rb'
+ - 'spec/services/ci/register_job_service_spec.rb'
+ - 'spec/services/ci/retry_build_service_spec.rb'
+ - 'spec/services/deployments/after_create_service_spec.rb'
+ - 'spec/services/design_management/generate_image_versions_service_spec.rb'
+ - 'spec/services/draft_notes/destroy_service_spec.rb'
+ - 'spec/services/emails/confirm_service_spec.rb'
+ - 'spec/services/groups/destroy_service_spec.rb'
+ - 'spec/services/groups/import_export/import_service_spec.rb'
+ - 'spec/services/issuable/clone/attributes_rewriter_spec.rb'
+ - 'spec/services/issuable/common_system_notes_service_spec.rb'
+ - 'spec/services/issues/close_service_spec.rb'
+ - 'spec/services/issues/create_service_spec.rb'
+ - 'spec/services/issues/export_csv_service_spec.rb'
+ - 'spec/services/issues/reopen_service_spec.rb'
+ - 'spec/services/issues/update_service_spec.rb'
+ - 'spec/services/labels/promote_service_spec.rb'
+ - 'spec/services/members/destroy_service_spec.rb'
+ - 'spec/services/merge_requests/conflicts/list_service_spec.rb'
+ - 'spec/services/merge_requests/create_service_spec.rb'
+ - 'spec/services/merge_requests/merge_service_spec.rb'
+ - 'spec/services/merge_requests/post_merge_service_spec.rb'
+ - 'spec/services/merge_requests/refresh_service_spec.rb'
+ - 'spec/services/merge_requests/update_service_spec.rb'
+ - 'spec/services/milestones/destroy_service_spec.rb'
+ - 'spec/services/milestones/promote_service_spec.rb'
+ - 'spec/services/milestones/transfer_service_spec.rb'
+ - 'spec/services/notification_recipients/build_service_spec.rb'
+ - 'spec/services/notification_service_spec.rb'
+ - 'spec/services/projects/after_rename_service_spec.rb'
+ - 'spec/services/projects/create_service_spec.rb'
+ - 'spec/services/projects/fork_service_spec.rb'
+ - 'spec/services/projects/move_access_service_spec.rb'
+ - 'spec/services/projects/move_project_group_links_service_spec.rb'
+ - 'spec/services/projects/overwrite_project_service_spec.rb'
+ - 'spec/services/projects/propagate_service_template_spec.rb'
+ - 'spec/services/projects/unlink_fork_service_spec.rb'
+ - 'spec/services/projects/update_pages_service_spec.rb'
+ - 'spec/services/projects/update_service_spec.rb'
+ - 'spec/services/quick_actions/interpret_service_spec.rb'
+ - 'spec/services/system_hooks_service_spec.rb'
+ - 'spec/services/system_note_service_spec.rb'
+ - 'spec/services/system_notes/issuables_service_spec.rb'
+ - 'spec/services/todo_service_spec.rb'
+ - 'spec/services/todos/destroy/confidential_issue_service_spec.rb'
+ - 'spec/services/users/destroy_service_spec.rb'
+ - 'spec/services/users/repair_ldap_blocked_service_spec.rb'
+ - 'spec/support/helpers/cycle_analytics_helpers.rb'
+ - 'spec/support/helpers/jira_service_helper.rb'
+ - 'spec/support/helpers/login_helpers.rb'
+ - 'spec/support/helpers/notification_helpers.rb'
+ - 'spec/support/helpers/stub_action_cable_connection.rb'
+ - 'spec/support/helpers/stub_object_storage.rb'
+ - 'spec/support/migrations_helpers/cluster_helpers.rb'
+ - 'spec/support/migrations_helpers/track_untracked_uploads_helpers.rb'
+ - 'spec/support/shared_contexts/finders/group_projects_finder_shared_contexts.rb'
+ - 'spec/support/shared_contexts/mailers/notify_shared_context.rb'
+ - 'spec/support/shared_examples/controllers/githubish_import_controller_shared_examples.rb'
+ - 'spec/support/shared_examples/controllers/sessionless_auth_controller_shared_examples.rb'
+ - 'spec/support/shared_examples/features/editable_merge_request_shared_examples.rb'
+ - 'spec/support/shared_examples/lib/gitlab/ci/ci_trace_shared_examples.rb'
+ - 'spec/support/shared_examples/models/diff_note_after_commit_shared_examples.rb'
+ - 'spec/support/shared_examples/models/member_shared_examples.rb'
+ - 'spec/support/shared_examples/models/members_notifications_shared_example.rb'
+ - 'spec/support/shared_examples/models/mentionable_shared_examples.rb'
+ - 'spec/support/shared_examples/models/relative_positioning_shared_examples.rb'
+ - 'spec/support/shared_examples/models/slack_mattermost_notifications_shared_examples.rb'
+ - 'spec/support/shared_examples/models/update_project_statistics_shared_examples.rb'
+ - 'spec/support/shared_examples/models/with_uploads_shared_examples.rb'
+ - 'spec/support/shared_examples/quick_actions/issuable/issuable_quick_actions_shared_examples.rb'
+ - 'spec/support/shared_examples/quick_actions/merge_request/merge_quick_action_shared_examples.rb'
+ - 'spec/support/shared_examples/requests/api/boards_shared_examples.rb'
+ - 'spec/support/shared_examples/services/common_system_notes_shared_examples.rb'
+ - 'spec/support/shared_examples/services/issuable_shared_examples.rb'
+ - 'spec/tasks/gitlab/web_hook_rake_spec.rb'
+ - 'spec/views/projects/imports/new.html.haml_spec.rb'
+ - 'spec/views/projects/merge_requests/show.html.haml_spec.rb'
+ - 'spec/views/shared/_label_row.html.haml_spec.rb'
+ - 'spec/workers/migrate_external_diffs_worker_spec.rb'
+ - 'spec/workers/namespaceless_project_destroy_worker_spec.rb'
+ - 'spec/workers/pages_domain_verification_worker_spec.rb'
+ - 'spec/workers/propagate_service_template_worker_spec.rb'
+ - 'spec/workers/remove_unreferenced_lfs_objects_worker_spec.rb'
+ - 'spec/workers/repository_cleanup_worker_spec.rb'
+ - 'spec/workers/repository_import_worker_spec.rb'
+ - 'spec/workers/repository_update_remote_mirror_worker_spec.rb'
diff --git a/app/assets/javascripts/alert_management/components/alert_management_list.vue b/app/assets/javascripts/alert_management/components/alert_management_list.vue
index d7972de62d9..e2098c851d1 100644
--- a/app/assets/javascripts/alert_management/components/alert_management_list.vue
+++ b/app/assets/javascripts/alert_management/components/alert_management_list.vue
@@ -282,9 +282,7 @@ export default {
},
getAssignees(assignees) {
// TODO: Update to show list of assignee(s) after https://gitlab.com/gitlab-org/gitlab/-/issues/218405
- return assignees.nodes?.length > 0
- ? assignees.nodes[0]?.username
- : s__('AlertManagement|Unassigned');
+ return assignees?.length > 0 ? assignees[0]?.username : s__('AlertManagement|Unassigned');
},
handlePageChange(page) {
const { startCursor, endCursor } = this.alerts.pageInfo;
diff --git a/app/assets/javascripts/alert_management/graphql/fragments/list_item.fragment.graphql b/app/assets/javascripts/alert_management/graphql/fragments/list_item.fragment.graphql
index 746c4435f38..003aa9ac0f0 100644
--- a/app/assets/javascripts/alert_management/graphql/fragments/list_item.fragment.graphql
+++ b/app/assets/javascripts/alert_management/graphql/fragments/list_item.fragment.graphql
@@ -6,10 +6,8 @@ fragment AlertListItem on AlertManagementAlert {
startedAt
endedAt
eventCount
- issueIid
+ issueIid,
assignees {
- nodes {
- username
- }
- }
+ username
+ },
}
diff --git a/app/assets/javascripts/clusters_list/components/clusters.vue b/app/assets/javascripts/clusters_list/components/clusters.vue
index 0404c8cdfed..58b16f35347 100644
--- a/app/assets/javascripts/clusters_list/components/clusters.vue
+++ b/app/assets/javascripts/clusters_list/components/clusters.vue
@@ -1,10 +1,12 @@
<script>
+import * as Sentry from '@sentry/browser';
import { mapState, mapActions } from 'vuex';
import {
GlDeprecatedBadge as GlBadge,
GlLink,
GlLoadingIcon,
GlPagination,
+ GlSprintf,
GlTable,
} from '@gitlab/ui';
import tooltip from '~/vue_shared/directives/tooltip';
@@ -12,11 +14,14 @@ import { CLUSTER_TYPES, STATUSES } from '../constants';
import { __, sprintf } from '~/locale';
export default {
+ nodeMemoryText: __('%{totalMemory} (%{freeSpacePercentage}%{percentSymbol} free)'),
+ nodeCpuText: __('%{totalCpu} (%{freeSpacePercentage}%{percentSymbol} free)'),
components: {
GlBadge,
GlLink,
GlLoadingIcon,
GlPagination,
+ GlSprintf,
GlTable,
},
directives: {
@@ -47,15 +52,14 @@ export default {
key: 'node_size',
label: __('Nodes'),
},
- // Fields are missing calculation methods and not ready to display
- // {
- // key: 'node_cpu',
- // label: __('Total cores (vCPUs)'),
- // },
- // {
- // key: 'node_memory',
- // label: __('Total memory (GB)'),
- // },
+ {
+ key: 'total_cpu',
+ label: __('Total cores (CPUs)'),
+ },
+ {
+ key: 'total_memory',
+ label: __('Total memory (GB)'),
+ },
{
key: 'cluster_type',
label: __('Cluster level'),
@@ -72,11 +76,102 @@ export default {
},
methods: {
...mapActions(['fetchClusters', 'setPage']),
+ k8sQuantityToGb(quantity) {
+ if (!quantity) {
+ return 0;
+ } else if (quantity.endsWith(__('Ki'))) {
+ return parseInt(quantity.substr(0, quantity.length - 2), 10) * 0.000001024;
+ } else if (quantity.endsWith(__('Mi'))) {
+ return parseInt(quantity.substr(0, quantity.length - 2), 10) * 0.001048576;
+ }
+ // We are trying to track quantity types coming from Kubernetes.
+ // Sentry will notify us if we are missing types.
+ throw new Error(`UnknownK8sMemoryQuantity:${quantity}`);
+ },
+ k8sQuantityToCpu(quantity) {
+ if (!quantity) {
+ return 0;
+ } else if (quantity.endsWith('m')) {
+ return parseInt(quantity.substr(0, quantity.length - 1), 10) / 1000.0;
+ } else if (quantity.endsWith('n')) {
+ return parseInt(quantity.substr(0, quantity.length - 1), 10) / 1000000000.0;
+ }
+
+ // We are trying to track quantity types coming from Kubernetes.
+ // Sentry will notify us if we are missing types.
+ throw new Error(`UnknownK8sCpuQuantity:${quantity}`);
+ },
statusTitle(status) {
const iconTitle = STATUSES[status] || STATUSES.default;
return sprintf(__('Status: %{title}'), { title: iconTitle.title }, false);
},
+ totalMemoryAndUsage(nodes) {
+ try {
+ // For EKS node.usage will not be present unless the user manually
+ // install the metrics server
+ if (nodes && nodes[0].usage) {
+ let totalAllocatableMemory = 0;
+ let totalUsedMemory = 0;
+
+ nodes.reduce((total, node) => {
+ const allocatableMemoryQuantity = node.status.allocatable.memory;
+ const allocatableMemoryGb = this.k8sQuantityToGb(allocatableMemoryQuantity);
+ totalAllocatableMemory += allocatableMemoryGb;
+
+ const usedMemoryQuantity = node.usage.memory;
+ const usedMemoryGb = this.k8sQuantityToGb(usedMemoryQuantity);
+ totalUsedMemory += usedMemoryGb;
+
+ return null;
+ }, 0);
+
+ const freeSpacePercentage = (1 - totalUsedMemory / totalAllocatableMemory) * 100;
+
+ return {
+ totalMemory: totalAllocatableMemory.toFixed(2),
+ freeSpacePercentage: Math.round(freeSpacePercentage),
+ };
+ }
+ } catch (error) {
+ Sentry.captureException(error);
+ }
+
+ return { totalMemory: null, freeSpacePercentage: null };
+ },
+ totalCpuAndUsage(nodes) {
+ try {
+ // For EKS node.usage will not be present unless the user manually
+ // install the metrics server
+ if (nodes && nodes[0].usage) {
+ let totalAllocatableCpu = 0;
+ let totalUsedCpu = 0;
+
+ nodes.reduce((total, node) => {
+ const allocatableCpuQuantity = node.status.allocatable.cpu;
+ const allocatableCpu = this.k8sQuantityToCpu(allocatableCpuQuantity);
+ totalAllocatableCpu += allocatableCpu;
+
+ const usedCpuQuantity = node.usage.cpu;
+ const usedCpuGb = this.k8sQuantityToCpu(usedCpuQuantity);
+ totalUsedCpu += usedCpuGb;
+
+ return null;
+ }, 0);
+
+ const freeSpacePercentage = (1 - totalUsedCpu / totalAllocatableCpu) * 100;
+
+ return {
+ totalCpu: totalAllocatableCpu.toFixed(2),
+ freeSpacePercentage: Math.round(freeSpacePercentage),
+ };
+ }
+ } catch (error) {
+ Sentry.captureException(error);
+ }
+
+ return { totalCpu: null, freeSpacePercentage: null };
+ },
},
};
</script>
@@ -109,6 +204,34 @@ export default {
}}</small>
</template>
+ <template #cell(total_cpu)="{ item }">
+ <span v-if="item.nodes">
+ <gl-sprintf :message="$options.nodeCpuText">
+ <template #totalCpu>{{ totalCpuAndUsage(item.nodes).totalCpu }}</template>
+ <template #freeSpacePercentage>{{
+ totalCpuAndUsage(item.nodes).freeSpacePercentage
+ }}</template>
+ <template #percentSymbol
+ >%</template
+ >
+ </gl-sprintf>
+ </span>
+ </template>
+
+ <template #cell(total_memory)="{ item }">
+ <span v-if="item.nodes">
+ <gl-sprintf :message="$options.nodeMemoryText">
+ <template #totalMemory>{{ totalMemoryAndUsage(item.nodes).totalMemory }}</template>
+ <template #freeSpacePercentage>{{
+ totalMemoryAndUsage(item.nodes).freeSpacePercentage
+ }}</template>
+ <template #percentSymbol
+ >%</template
+ >
+ </gl-sprintf>
+ </span>
+ </template>
+
<template #cell(cluster_type)="{value}">
<gl-badge variant="light">
{{ value }}
diff --git a/app/controllers/repositories/git_http_controller.rb b/app/controllers/repositories/git_http_controller.rb
index e3dbe6fcbdf..6a27d63625e 100644
--- a/app/controllers/repositories/git_http_controller.rb
+++ b/app/controllers/repositories/git_http_controller.rb
@@ -9,7 +9,7 @@ module Repositories
rescue_from Gitlab::GitAccess::ForbiddenError, with: :render_403_with_exception
rescue_from Gitlab::GitAccess::NotFoundError, with: :render_404_with_exception
- rescue_from Gitlab::GitAccess::ProjectCreationError, with: :render_422_with_exception
+ rescue_from Gitlab::GitAccessProject::CreationError, with: :render_422_with_exception
rescue_from Gitlab::GitAccess::TimeoutError, with: :render_503_with_exception
# GET /foo/bar.git/info/refs?service=git-upload-pack (git pull)
diff --git a/app/graphql/resolvers/alert_management/alerts/assignees_resolver.rb b/app/graphql/resolvers/alert_management/alerts/assignees_resolver.rb
deleted file mode 100644
index 208b30b7f01..00000000000
--- a/app/graphql/resolvers/alert_management/alerts/assignees_resolver.rb
+++ /dev/null
@@ -1,35 +0,0 @@
-# frozen_string_literal: true
-
-module Resolvers
- module AlertManagement
- module Alerts
- class AssigneesResolver < BaseResolver
- type Types::UserType, null: true
-
- # With lazy-loaded assignees, authorizations should be avoided
- # in earlier phases to take advantage of batching. See
- # AssigneeLoader for authorization steps.
- # https://gitlab.com/gitlab-org/gitlab/-/issues/217767
- def self.skip_authorizations?
- true
- end
-
- def resolve(**args)
- return [] unless Feature.enabled?(:alert_assignee)
-
- ::Gitlab::Graphql::Loaders::AlertManagement::Alerts::AssigneesLoader
- .new(object.id, user_authorization_filter)
- .find
- end
-
- private
-
- def user_authorization_filter
- proc do |users|
- users.select { |user| Ability.allowed?(context[:current_user], :read_user, user) }
- end
- end
- end
- end
- end
-end
diff --git a/app/graphql/types/alert_management/alert_type.rb b/app/graphql/types/alert_management/alert_type.rb
index ae5fc7c28e8..1630bf4491d 100644
--- a/app/graphql/types/alert_management/alert_type.rb
+++ b/app/graphql/types/alert_management/alert_type.rb
@@ -85,10 +85,15 @@ module Types
description: 'Timestamp the alert was last updated'
field :assignees,
- Types::UserType.connection_type,
+ [Types::UserType],
null: true,
- description: 'Assignees of the alert',
- resolver: ::Resolvers::AlertManagement::Alerts::AssigneesResolver
+ description: 'Assignees of the alert'
+
+ def assignees
+ return User.none unless Feature.enabled?(:alert_assignee, object.project)
+
+ object.assignees
+ end
end
end
end
diff --git a/app/models/alert_management/alert_assignee.rb b/app/models/alert_management/alert_assignee.rb
index 91a52bf8f74..c74b2699182 100644
--- a/app/models/alert_management/alert_assignee.rb
+++ b/app/models/alert_management/alert_assignee.rb
@@ -7,7 +7,5 @@ module AlertManagement
validates :alert, presence: true
validates :assignee, presence: true, uniqueness: { scope: :alert_id }
-
- scope :for_alert_ids, -> (ids) { includes(:assignee).where(alert_id: ids) }
end
end
diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb
index c919f57a8fc..755e704aeaa 100644
--- a/app/models/ci/pipeline.rb
+++ b/app/models/ci/pipeline.rb
@@ -800,13 +800,17 @@ module Ci
@latest_builds_with_artifacts ||= builds.latest.with_artifacts_not_expired.to_a
end
+ def latest_report_builds(reports_scope = ::Ci::JobArtifact.with_reports)
+ builds.latest.with_reports(reports_scope)
+ end
+
def has_reports?(reports_scope)
- complete? && builds.latest.with_reports(reports_scope).exists?
+ complete? && latest_report_builds(reports_scope).exists?
end
def test_reports
Gitlab::Ci::Reports::TestReports.new.tap do |test_reports|
- builds.latest.with_reports(Ci::JobArtifact.test_reports).preload(:project).find_each do |build|
+ latest_report_builds(Ci::JobArtifact.test_reports).preload(:project).find_each do |build|
build.collect_test_reports!(test_reports)
end
end
@@ -828,7 +832,7 @@ module Ci
def coverage_reports
Gitlab::Ci::Reports::CoverageReports.new.tap do |coverage_reports|
- builds.latest.with_reports(Ci::JobArtifact.coverage_reports).each do |build|
+ latest_report_builds(Ci::JobArtifact.coverage_reports).each do |build|
build.collect_coverage_reports!(coverage_reports)
end
end
@@ -836,7 +840,7 @@ module Ci
def terraform_reports
::Gitlab::Ci::Reports::TerraformReports.new.tap do |terraform_reports|
- builds.latest.with_reports(::Ci::JobArtifact.terraform_reports).each do |build|
+ latest_report_builds(::Ci::JobArtifact.terraform_reports).each do |build|
build.collect_terraform_reports!(terraform_reports)
end
end
diff --git a/app/models/clusters/cluster.rb b/app/models/clusters/cluster.rb
index 73eb0ee22c0..81107bb00e3 100644
--- a/app/models/clusters/cluster.rb
+++ b/app/models/clusters/cluster.rb
@@ -373,7 +373,10 @@ module Clusters
def retrieve_nodes
result = ::Gitlab::Kubernetes::KubeClient.graceful_request(id) { kubeclient.get_nodes }
- cluster_nodes = result[:response].to_a
+
+ return unless result[:response]
+
+ cluster_nodes = result[:response]
result = ::Gitlab::Kubernetes::KubeClient.graceful_request(id) { kubeclient.metrics_client.get_nodes }
nodes_metrics = result[:response].to_a
diff --git a/changelogs/unreleased/215668-settings-auto-fix.yml b/changelogs/unreleased/215668-settings-auto-fix.yml
new file mode 100644
index 00000000000..b0ac2c15fcf
--- /dev/null
+++ b/changelogs/unreleased/215668-settings-auto-fix.yml
@@ -0,0 +1,5 @@
+---
+title: Add model for project level security auto-fix settings
+merge_request: 32577
+author:
+type: added
diff --git a/changelogs/unreleased/feature-show-memory-cpu-on-cluster-list.yml b/changelogs/unreleased/feature-show-memory-cpu-on-cluster-list.yml
new file mode 100644
index 00000000000..e3375d85821
--- /dev/null
+++ b/changelogs/unreleased/feature-show-memory-cpu-on-cluster-list.yml
@@ -0,0 +1,5 @@
+---
+title: Adds cluster CPU and Memory to cluster index
+merge_request: 32601
+author:
+type: changed
diff --git a/config/webpack.config.js b/config/webpack.config.js
index c17734ed3dc..557db58b1b9 100644
--- a/config/webpack.config.js
+++ b/config/webpack.config.js
@@ -19,10 +19,11 @@ const IS_EE = require('./helpers/is_ee_env');
const DEV_SERVER_HOST = process.env.DEV_SERVER_HOST || 'localhost';
const DEV_SERVER_PORT = parseInt(process.env.DEV_SERVER_PORT, 10) || 3808;
const DEV_SERVER_LIVERELOAD = IS_DEV_SERVER && process.env.DEV_SERVER_LIVERELOAD !== 'false';
-const WEBPACK_REPORT = process.env.WEBPACK_REPORT;
-const WEBPACK_MEMORY_TEST = process.env.WEBPACK_MEMORY_TEST;
-const NO_COMPRESSION = process.env.NO_COMPRESSION;
-const NO_SOURCEMAPS = process.env.NO_SOURCEMAPS;
+const WEBPACK_REPORT = process.env.WEBPACK_REPORT && process.env.WEBPACK_REPORT !== 'false';
+const WEBPACK_MEMORY_TEST =
+ process.env.WEBPACK_MEMORY_TEST && process.env.WEBPACK_MEMORY_TEST !== 'false';
+const NO_COMPRESSION = process.env.NO_COMPRESSION && process.env.NO_COMPRESSION !== 'false';
+const NO_SOURCEMAPS = process.env.NO_SOURCEMAPS && process.env.NO_SOURCEMAPS !== 'false';
const VUE_VERSION = require('vue/package.json').version;
const VUE_LOADER_VERSION = require('vue-loader/package.json').version;
diff --git a/db/migrate/20200604143628_create_project_security_settings.rb b/db/migrate/20200604143628_create_project_security_settings.rb
new file mode 100644
index 00000000000..f972cb509a7
--- /dev/null
+++ b/db/migrate/20200604143628_create_project_security_settings.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+class CreateProjectSecuritySettings < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ def up
+ with_lock_retries do
+ create_table :project_security_settings, id: false do |t|
+ t.references :project, primary_key: true, index: false, foreign_key: { on_delete: :cascade }
+ t.timestamps_with_timezone
+
+ t.boolean :auto_fix_container_scanning, default: true, null: false
+ t.boolean :auto_fix_dast, default: true, null: false
+ t.boolean :auto_fix_dependency_scanning, default: true, null: false
+ t.boolean :auto_fix_sast, default: true, null: false
+ end
+ end
+ end
+
+ def down
+ with_lock_retries do
+ drop_table :project_security_settings
+ end
+ end
+end
diff --git a/db/structure.sql b/db/structure.sql
index f5006c09830..861544f2550 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -5316,6 +5316,25 @@ CREATE SEQUENCE public.project_repository_storage_moves_id_seq
ALTER SEQUENCE public.project_repository_storage_moves_id_seq OWNED BY public.project_repository_storage_moves.id;
+CREATE TABLE public.project_security_settings (
+ project_id bigint NOT NULL,
+ created_at timestamp with time zone NOT NULL,
+ updated_at timestamp with time zone NOT NULL,
+ auto_fix_container_scanning boolean DEFAULT true NOT NULL,
+ auto_fix_dast boolean DEFAULT true NOT NULL,
+ auto_fix_dependency_scanning boolean DEFAULT true NOT NULL,
+ auto_fix_sast boolean DEFAULT true NOT NULL
+);
+
+CREATE SEQUENCE public.project_security_settings_project_id_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+ALTER SEQUENCE public.project_security_settings_project_id_seq OWNED BY public.project_security_settings.project_id;
+
CREATE TABLE public.project_settings (
project_id integer NOT NULL,
created_at timestamp with time zone NOT NULL,
@@ -7822,6 +7841,8 @@ ALTER TABLE ONLY public.project_repository_states ALTER COLUMN id SET DEFAULT ne
ALTER TABLE ONLY public.project_repository_storage_moves ALTER COLUMN id SET DEFAULT nextval('public.project_repository_storage_moves_id_seq'::regclass);
+ALTER TABLE ONLY public.project_security_settings ALTER COLUMN project_id SET DEFAULT nextval('public.project_security_settings_project_id_seq'::regclass);
+
ALTER TABLE ONLY public.project_statistics ALTER COLUMN id SET DEFAULT nextval('public.project_statistics_id_seq'::regclass);
ALTER TABLE ONLY public.project_tracing_settings ALTER COLUMN id SET DEFAULT nextval('public.project_tracing_settings_id_seq'::regclass);
@@ -8748,6 +8769,9 @@ ALTER TABLE ONLY public.project_repository_states
ALTER TABLE ONLY public.project_repository_storage_moves
ADD CONSTRAINT project_repository_storage_moves_pkey PRIMARY KEY (id);
+ALTER TABLE ONLY public.project_security_settings
+ ADD CONSTRAINT project_security_settings_pkey PRIMARY KEY (project_id);
+
ALTER TABLE ONLY public.project_settings
ADD CONSTRAINT project_settings_pkey PRIMARY KEY (project_id);
@@ -12711,6 +12735,9 @@ ALTER TABLE ONLY public.ci_daily_report_results
ALTER TABLE ONLY public.cluster_providers_aws
ADD CONSTRAINT fk_rails_ed1fdfaeb2 FOREIGN KEY (created_by_user_id) REFERENCES public.users(id) ON DELETE SET NULL;
+ALTER TABLE ONLY public.project_security_settings
+ ADD CONSTRAINT fk_rails_ed4abe1338 FOREIGN KEY (project_id) REFERENCES public.projects(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY public.ci_daily_build_group_report_results
ADD CONSTRAINT fk_rails_ee072d13b3 FOREIGN KEY (last_pipeline_id) REFERENCES public.ci_pipelines(id) ON DELETE CASCADE;
@@ -13806,5 +13833,6 @@ COPY "schema_migrations" (version) FROM STDIN;
20200528171933
20200601210148
20200603073101
+20200604143628
\.
diff --git a/doc/api/graphql/reference/gitlab_schema.graphql b/doc/api/graphql/reference/gitlab_schema.graphql
index ce338ef875a..b0cc72965aa 100644
--- a/doc/api/graphql/reference/gitlab_schema.graphql
+++ b/doc/api/graphql/reference/gitlab_schema.graphql
@@ -172,27 +172,7 @@ type AlertManagementAlert {
"""
Assignees of the alert
"""
- assignees(
- """
- Returns the elements in the list that come after the specified cursor.
- """
- after: String
-
- """
- Returns the elements in the list that come before the specified cursor.
- """
- before: String
-
- """
- Returns the first _n_ elements from the list.
- """
- first: Int
-
- """
- Returns the last _n_ elements from the list.
- """
- last: Int
- ): UserConnection
+ assignees: [User!]
"""
Timestamp the alert was created
diff --git a/doc/api/graphql/reference/gitlab_schema.json b/doc/api/graphql/reference/gitlab_schema.json
index 9ac10a14575..10b34f6af91 100644
--- a/doc/api/graphql/reference/gitlab_schema.json
+++ b/doc/api/graphql/reference/gitlab_schema.json
@@ -486,51 +486,20 @@
"name": "assignees",
"description": "Assignees of the alert",
"args": [
- {
- "name": "after",
- "description": "Returns the elements in the list that come after the specified cursor.",
- "type": {
- "kind": "SCALAR",
- "name": "String",
- "ofType": null
- },
- "defaultValue": null
- },
- {
- "name": "before",
- "description": "Returns the elements in the list that come before the specified cursor.",
- "type": {
- "kind": "SCALAR",
- "name": "String",
- "ofType": null
- },
- "defaultValue": null
- },
- {
- "name": "first",
- "description": "Returns the first _n_ elements from the list.",
- "type": {
- "kind": "SCALAR",
- "name": "Int",
- "ofType": null
- },
- "defaultValue": null
- },
- {
- "name": "last",
- "description": "Returns the last _n_ elements from the list.",
- "type": {
- "kind": "SCALAR",
- "name": "Int",
- "ofType": null
- },
- "defaultValue": null
- }
+
],
"type": {
- "kind": "OBJECT",
- "name": "UserConnection",
- "ofType": null
+ "kind": "LIST",
+ "name": null,
+ "ofType": {
+ "kind": "NON_NULL",
+ "name": null,
+ "ofType": {
+ "kind": "OBJECT",
+ "name": "User",
+ "ofType": null
+ }
+ }
},
"isDeprecated": false,
"deprecationReason": null
diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md
index 802b118b170..96bac1d3549 100644
--- a/doc/api/graphql/reference/index.md
+++ b/doc/api/graphql/reference/index.md
@@ -61,6 +61,7 @@ Describes an alert from the project's Alert Management
| Name | Type | Description |
| --- | ---- | ---------- |
+| `assignees` | User! => Array | Assignees of the alert |
| `createdAt` | Time | Timestamp the alert was created |
| `description` | String | Description of the alert |
| `details` | JSON | Alert details |
diff --git a/doc/ci/environments/incremental_rollouts.md b/doc/ci/environments/incremental_rollouts.md
index c35e7cac0e5..5da5c8e0a87 100644
--- a/doc/ci/environments/incremental_rollouts.md
+++ b/doc/ci/environments/incremental_rollouts.md
@@ -117,7 +117,7 @@ available, [demonstrating configuration of timed rollouts](https://gitlab.com/gl
## Blue-Green Deployment
-Also sometimes known as canary or red-black deployment, this technique is used to reduce
+Also sometimes known as A/B deployment or red-black deployment, this technique is used to reduce
downtime and risk during a deployment. When combined with incremental rollouts, you can
minimize the impact of a deployment causing an issue.
diff --git a/doc/development/telemetry/usage_ping.md b/doc/development/telemetry/usage_ping.md
index d8fa50ac47a..975268bcd4a 100644
--- a/doc/development/telemetry/usage_ping.md
+++ b/doc/development/telemetry/usage_ping.md
@@ -289,7 +289,11 @@ Examples of query optimization work:
- [Example 1](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/26445)
- [Example 2](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/26871)
-### 4. Ask for a Telemetry Review
+### 4. Add the metric definition
+
+When adding, changing, or updating metrics, please update the [Usage Statistics definition table](#usage-statistics-definitions).
+
+### 5. Ask for a Telemetry Review
On GitLab.com, we have DangerBot setup to monitor Telemetry related files and DangerBot will recommend a Telemetry review. Mention `@gitlab-org/growth/telemetry/engineers` in your MR for a review.
diff --git a/doc/user/application_security/dependency_scanning/index.md b/doc/user/application_security/dependency_scanning/index.md
index 7fffbbde5cd..6eb1cde7bbb 100644
--- a/doc/user/application_security/dependency_scanning/index.md
+++ b/doc/user/application_security/dependency_scanning/index.md
@@ -56,20 +56,24 @@ Beginning with GitLab 13.0, Docker privileged mode is necessary only if you've [
GitLab relies on [`rules`](../../../ci/yaml/README.md#rules) to start relevant analyzers depending on the languages detected in the repository.
The current detection logic limits the maximum search depth to two levels. For example, the `gemnasium-dependency_scanning` job is enabled if a repository contains either a `Gemfile` or `api/Gemfile` file, but not if the only supported dependency file is `api/client/Gemfile`.
-The following languages and dependency managers are supported.
-
-| Language (package managers) | Supported | Scan tool(s) |
-|----------------------------- | --------- | ------------ |
-| Java ([Gradle](https://gradle.org/)) | yes | [Gemnasium](https://gitlab.com/gitlab-org/security-products/gemnasium) |
-| Java ([Maven](https://maven.apache.org/)) | yes | [Gemnasium](https://gitlab.com/gitlab-org/security-products/gemnasium) |
-| JavaScript ([npm](https://www.npmjs.com/), [yarn](https://classic.yarnpkg.com/en/)) | yes | [Gemnasium](https://gitlab.com/gitlab-org/security-products/gemnasium), [Retire.js](https://retirejs.github.io/retire.js/) |
-| PHP ([Composer](https://getcomposer.org/)) | yes | [Gemnasium](https://gitlab.com/gitlab-org/security-products/gemnasium) |
-| Python ([pip](https://pip.pypa.io/en/stable/)) | yes | [Gemnasium](https://gitlab.com/gitlab-org/security-products/gemnasium) |
-| Python ([Pipfile](https://pipenv.kennethreitz.org/en/latest/basics/)) | not currently ([issue](https://gitlab.com/gitlab-org/gitlab/-/issues/11756 "Pipfile.lock support for Dependency Scanning"))| not available |
-| Python ([poetry](https://python-poetry.org/)) | not currently ([issue](https://gitlab.com/gitlab-org/gitlab/-/issues/7006 "Support Poetry in Dependency Scanning")) | not available |
-| Ruby ([gem](https://rubygems.org/)) | yes | [Gemnasium](https://gitlab.com/gitlab-org/security-products/gemnasium), [bundler-audit](https://github.com/rubysec/bundler-audit) |
-| Scala ([sbt](https://www.scala-sbt.org/)) | yes | [Gemnasium](https://gitlab.com/gitlab-org/security-products/gemnasium) |
-| Go ([Go Modules](https://github.com/golang/go/wiki/Modules)) | yes ([alpha](https://gitlab.com/gitlab-org/gitlab/-/issues/7132)) | [Gemnasium](https://gitlab.com/gitlab-org/security-products/gemnasium) |
+The following languages and dependency managers are supported:
+
+| Language (package managers) | Supported files | Scan tool(s) |
+|----------------------------- | --------------- | ------------ |
+| Java ([Gradle](https://gradle.org/), [Maven](https://maven.apache.org/)) | `build.gradle`, `build.gradle.kts`, `pom.xml` | [Gemnasium](https://gitlab.com/gitlab-org/security-products/gemnasium) |
+| JavaScript ([npm](https://www.npmjs.com/), [yarn](https://yarnpkg.com/en/)) | `package-lock.json`, `npm-shrinkwrap.json`, `yarn.lock` | [Gemnasium](https://gitlab.com/gitlab-org/security-products/gemnasium), [Retire.js](https://retirejs.github.io/retire.js) |
+| Go ([Golang](https://golang.org/)) | `go.sum` | [Gemnasium](https://gitlab.com/gitlab-org/security-products/gemnasium) |
+| PHP ([Composer](https://getcomposer.org/)) | `composer.lock` | [Gemnasium](https://gitlab.com/gitlab-org/security-products/gemnasium) |
+| Python ([setuptools](https://setuptools.readthedocs.io/en/latest/), [pip](https://pip.pypa.io/en/stable/), [Pipenv](https://pipenv.pypa.io/en/latest/)) | `setup.py`, `requirements.txt`, `requirements.pip`, `requires.txt`, `Pipfile` | [Gemnasium](https://gitlab.com/gitlab-org/security-products/gemnasium) |
+| Ruby ([Bundler](https://bundler.io/)) | `Gemfile.lock`, `gems.locked` | [Gemnasium](https://gitlab.com/gitlab-org/security-products/gemnasium), [bundler-audit](https://github.com/rubysec/bundler-audit) |
+| Scala ([sbt](https://www.scala-sbt.org/)) | `build.sbt` | [Gemnasium](https://gitlab.com/gitlab-org/security-products/gemnasium) |
+
+Plans are underway for supporting the following languages, dependency managers, and dependency files. For details, see the issue link for each.
+
+| Language (package managers) | Supported files | Scan tool(s) | Issue |
+|----------------------------- | --------------- | ------------ | ----- |
+| Python ([Poetry](https://poetry.eustace.io/)) | `poetry.lock` | [Gemnasium](https://gitlab.com/gitlab-org/security-products/gemnasium) | [GitLab#7006](https://gitlab.com/gitlab-org/gitlab/issues/7006) |
+| Python ([Pipenv](https://pipenv.pypa.io/en/latest/)) | `Pipfile.lock` | [Gemnasium](https://gitlab.com/gitlab-org/security-products/gemnasium) | [GitLab#11756](https://gitlab.com/gitlab-org/gitlab/-/issues/11756) |
## Contribute your scanner
diff --git a/doc/user/packages/container_registry/index.md b/doc/user/packages/container_registry/index.md
index 8779b3ea9bd..c5638a8a3cd 100644
--- a/doc/user/packages/container_registry/index.md
+++ b/doc/user/packages/container_registry/index.md
@@ -496,8 +496,9 @@ older tags and images are regularly removed from the Container Registry.
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/15398) in GitLab 12.8.
NOTE: **Note:**
-Expiration policies for projects created before GitLab 12.8 may be enabled by an
-admin in the [CI/CD Package Registry settings](./../../admin_area/settings/index.md#cicd).
+For GitLab.com, expiration policies are not available for projects created before GitLab 12.8.
+For self-managed instances, expiration policies may be enabled by an admin in the
+[CI/CD Package Registry settings](./../../admin_area/settings/index.md#cicd).
Note the inherent [risks involved](./index.md#use-with-external-container-registries).
It is possible to create a per-project expiration policy, so that you can make sure that
diff --git a/doc/user/project/pages/custom_domains_ssl_tls_certification/index.md b/doc/user/project/pages/custom_domains_ssl_tls_certification/index.md
index 6033d02df73..bf9b58acf14 100644
--- a/doc/user/project/pages/custom_domains_ssl_tls_certification/index.md
+++ b/doc/user/project/pages/custom_domains_ssl_tls_certification/index.md
@@ -287,6 +287,9 @@ To enable this setting:
1. Navigate to your project's **Settings > Pages**.
1. Tick the checkbox **Force HTTPS (requires valid certificates)**.
+NOTE: **Note**
+If you use CloudFlare CDN in front of GitLab Pages, make sure to set the SSL connection setting to `full` instead of `flexible`. For more details, see the [CloudFlare CDN directions](https://support.cloudflare.com/hc/en-us/articles/200170416-End-to-end-HTTPS-with-Cloudflare-Part-3-SSL-options#h_4e0d1a7c-eb71-4204-9e22-9d3ef9ef7fef).
+
<!-- ## Troubleshooting
Include any troubleshooting steps that you can foresee. If you know beforehand what issues
diff --git a/lib/gitlab/git_access.rb b/lib/gitlab/git_access.rb
index 6702c053fc7..37e3da984d6 100644
--- a/lib/gitlab/git_access.rb
+++ b/lib/gitlab/git_access.rb
@@ -8,7 +8,6 @@ module Gitlab
ForbiddenError = Class.new(StandardError)
NotFoundError = Class.new(StandardError)
- ProjectCreationError = Class.new(StandardError)
TimeoutError = Class.new(StandardError)
ProjectMovedError = Class.new(NotFoundError)
@@ -75,7 +74,7 @@ module Gitlab
check_db_accessibility!(cmd)
check_namespace!
- check_project!(changes, cmd)
+ check_project!(cmd)
check_repository_existence!
case cmd
@@ -112,8 +111,7 @@ module Gitlab
private
- def check_project!(changes, cmd)
- ensure_project_on_push!(cmd, changes)
+ def check_project!(_cmd)
check_project_accessibility!
add_project_moved_message!
end
@@ -230,32 +228,6 @@ module Gitlab
end
end
- def ensure_project_on_push!(cmd, changes)
- return if project || deploy_key?
- return unless receive_pack?(cmd) && changes == ANY && authentication_abilities.include?(:push_code)
-
- namespace = Namespace.find_by_full_path(namespace_path)
-
- return unless user&.can?(:create_projects, namespace)
-
- project_params = {
- path: repository_path,
- namespace_id: namespace.id,
- visibility_level: Gitlab::VisibilityLevel::PRIVATE
- }
-
- project = Projects::CreateService.new(user, project_params).execute
-
- unless project.saved?
- raise ProjectCreationError, "Could not create project: #{project.errors.full_messages.join(', ')}"
- end
-
- @project = project
- user_access.project = @project
-
- Checks::ProjectCreated.new(repository, user, protocol).add_message
- end
-
def check_repository_existence!
unless repository.exists?
raise NotFoundError, ERROR_MESSAGES[:no_repo]
diff --git a/lib/gitlab/git_access_project.rb b/lib/gitlab/git_access_project.rb
new file mode 100644
index 00000000000..c79a61c263e
--- /dev/null
+++ b/lib/gitlab/git_access_project.rb
@@ -0,0 +1,44 @@
+# frozen_string_literal: true
+
+module Gitlab
+ class GitAccessProject < GitAccess
+ extend ::Gitlab::Utils::Override
+
+ CreationError = Class.new(StandardError)
+
+ private
+
+ override :check_project!
+ def check_project!(cmd)
+ ensure_project_on_push!(cmd)
+
+ super
+ end
+
+ def ensure_project_on_push!(cmd)
+ return if project || deploy_key?
+ return unless receive_pack?(cmd) && changes == ANY && authentication_abilities.include?(:push_code)
+
+ namespace = Namespace.find_by_full_path(namespace_path)
+
+ return unless user&.can?(:create_projects, namespace)
+
+ project_params = {
+ path: repository_path,
+ namespace_id: namespace.id,
+ visibility_level: Gitlab::VisibilityLevel::PRIVATE
+ }
+
+ project = Projects::CreateService.new(user, project_params).execute
+
+ unless project.saved?
+ raise CreationError, "Could not create project: #{project.errors.full_messages.join(', ')}"
+ end
+
+ @project = project
+ user_access.project = @project
+
+ Checks::ProjectCreated.new(repository, user, protocol).add_message
+ end
+ end
+end
diff --git a/lib/gitlab/git_access_snippet.rb b/lib/gitlab/git_access_snippet.rb
index ba9920caf6f..3de6c9ee30a 100644
--- a/lib/gitlab/git_access_snippet.rb
+++ b/lib/gitlab/git_access_snippet.rb
@@ -47,11 +47,10 @@ module Gitlab
end
override :check_project!
- def check_project!(cmd, changes)
+ def check_project!(cmd)
return unless snippet.is_a?(ProjectSnippet)
- check_project_accessibility!
- add_project_moved_message!
+ super
end
override :check_push_access!
diff --git a/lib/gitlab/gl_repository.rb b/lib/gitlab/gl_repository.rb
index b75b4be9a4e..abd4e847a50 100644
--- a/lib/gitlab/gl_repository.rb
+++ b/lib/gitlab/gl_repository.rb
@@ -6,7 +6,7 @@ module Gitlab
PROJECT = RepoType.new(
name: :project,
- access_checker_class: Gitlab::GitAccess,
+ access_checker_class: Gitlab::GitAccessProject,
repository_resolver: -> (project) { project&.repository }
).freeze
WIKI = RepoType.new(
diff --git a/lib/gitlab/graphql/loaders/alert_management/alerts/assignees_loader.rb b/lib/gitlab/graphql/loaders/alert_management/alerts/assignees_loader.rb
deleted file mode 100644
index 7671dbb58ee..00000000000
--- a/lib/gitlab/graphql/loaders/alert_management/alerts/assignees_loader.rb
+++ /dev/null
@@ -1,52 +0,0 @@
-# frozen_string_literal: true
-
-module Gitlab
- module Graphql
- module Loaders
- module AlertManagement
- module Alerts
- # Batches requests for AlertManagement::Alert#assignees
- # to avoid N+1 queries
- class AssigneesLoader
- # @param alert_id [Integer]
- # @param authorization_filter [Proc] Filter to be applied
- # to output assignees
- def initialize(alert_id, authorization_filter)
- @alert_id = alert_id
- @authorization_filter = authorization_filter
- end
-
- # Returns BatchLoader::GraphQL which evaluates
- # to a Gitlab::Graphql::FilterableArray of User objects
- def find
- BatchLoader::GraphQL.for(alert_id).batch(default_value: default_value) do |alert_ids, loader|
- load_assignees(loader, alert_ids)
- end
- end
-
- private
-
- attr_reader :alert_id, :authorization_filter
-
- def default_value
- Gitlab::Graphql::FilterableArray.new(authorization_filter)
- end
-
- def load_assignees(loader, alert_ids)
- ::AlertManagement::AlertAssignee
- .for_alert_ids(alert_ids)
- .each { |alert_assignee| add_assignee_for_alert(loader, alert_assignee) }
- end
-
- def add_assignee_for_alert(loader, alert_assignee)
- # loader optionally accepts a block, allowing
- # access to the current expected output, allowing
- # us to collect assignees
- loader.call(alert_assignee.alert_id) { |assignees| assignees << alert_assignee.assignee }
- end
- end
- end
- end
- end
- end
-end
diff --git a/lib/gitlab/import_export/project/import_export.yml b/lib/gitlab/import_export/project/import_export.yml
index 8851b106ad5..a2213b67ee1 100644
--- a/lib/gitlab/import_export/project/import_export.yml
+++ b/lib/gitlab/import_export/project/import_export.yml
@@ -397,3 +397,4 @@ ee:
- protected_environments:
- :deploy_access_levels
- :service_desk_setting
+ - :security_setting
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index a28588496ba..e36decd3c00 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -622,6 +622,12 @@ msgstr ""
msgid "%{token}..."
msgstr ""
+msgid "%{totalCpu} (%{freeSpacePercentage}%{percentSymbol} free)"
+msgstr ""
+
+msgid "%{totalMemory} (%{freeSpacePercentage}%{percentSymbol} free)"
+msgstr ""
+
msgid "%{totalWeight} total weight"
msgstr ""
@@ -12641,6 +12647,9 @@ msgstr ""
msgid "Keyboard shortcuts"
msgstr ""
+msgid "Ki"
+msgstr ""
+
msgid "Kubernetes"
msgstr ""
@@ -14098,6 +14107,9 @@ msgstr ""
msgid "Metrics|e.g. req/sec"
msgstr ""
+msgid "Mi"
+msgstr ""
+
msgid "Microsoft Azure"
msgstr ""
@@ -23489,9 +23501,15 @@ msgstr ""
msgid "Total artifacts size: %{total_size}"
msgstr ""
+msgid "Total cores (CPUs)"
+msgstr ""
+
msgid "Total issues"
msgstr ""
+msgid "Total memory (GB)"
+msgstr ""
+
msgid "Total test time for all commits/merges"
msgstr ""
diff --git a/spec/frontend/alert_management/components/alert_management_list_spec.js b/spec/frontend/alert_management/components/alert_management_list_spec.js
index 39099f25150..b917d78dd95 100644
--- a/spec/frontend/alert_management/components/alert_management_list_spec.js
+++ b/spec/frontend/alert_management/components/alert_management_list_spec.js
@@ -262,7 +262,7 @@ describe('AlertManagementList', () => {
findAssignees()
.at(1)
.text(),
- ).toBe(mockAlerts[1].assignees.nodes[0].username);
+ ).toBe(mockAlerts[1].assignees[0].username);
});
it('navigates to the detail page when alert row is clicked', () => {
@@ -291,7 +291,6 @@ describe('AlertManagementList', () => {
startedAt: '2020-03-17T23:18:14.996Z',
endedAt: '2020-04-17T23:18:14.996Z',
severity: 'high',
- assignees: { nodes: [] },
},
],
},
diff --git a/spec/frontend/alert_management/mocks/alerts.json b/spec/frontend/alert_management/mocks/alerts.json
index 60bf075016c..402adc4675b 100644
--- a/spec/frontend/alert_management/mocks/alerts.json
+++ b/spec/frontend/alert_management/mocks/alerts.json
@@ -1,33 +1,33 @@
[
- {
- "iid": "1527542",
- "title": "SyntaxError: Invalid or unexpected token",
- "severity": "CRITICAL",
- "eventCount": 7,
- "createdAt": "2020-04-17T23:18:14.996Z",
- "startedAt": "2020-04-17T23:18:14.996Z",
- "endedAt": "2020-04-17T23:18:14.996Z",
- "status": "TRIGGERED",
- "assignees": { "nodes": [] }
- },
- {
- "iid": "1527543",
- "title": "Some other alert Some other alert Some other alert Some other alert Some other alert Some other alert",
- "severity": "MEDIUM",
- "eventCount": 1,
- "startedAt": "2020-04-17T23:18:14.996Z",
- "endedAt": "2020-04-17T23:18:14.996Z",
- "status": "ACKNOWLEDGED",
- "assignees": { "nodes": [{ "username": "root" }] }
- },
- {
- "iid": "1527544",
- "title": "SyntaxError: Invalid or unexpected token",
- "severity": "LOW",
- "eventCount": 4,
- "startedAt": "2020-04-17T23:18:14.996Z",
- "endedAt": "2020-04-17T23:18:14.996Z",
- "status": "RESOLVED",
- "assignees": { "nodes": [{ "username": "root" }] }
- }
-]
+ {
+ "iid": "1527542",
+ "title": "SyntaxError: Invalid or unexpected token",
+ "severity": "CRITICAL",
+ "eventCount": 7,
+ "createdAt": "2020-04-17T23:18:14.996Z",
+ "startedAt": "2020-04-17T23:18:14.996Z",
+ "endedAt": "2020-04-17T23:18:14.996Z",
+ "status": "TRIGGERED",
+ "assignees": []
+ },
+ {
+ "iid": "1527543",
+ "title": "Some other alert Some other alert Some other alert Some other alert Some other alert Some other alert",
+ "severity": "MEDIUM",
+ "eventCount": 1,
+ "startedAt": "2020-04-17T23:18:14.996Z",
+ "endedAt": "2020-04-17T23:18:14.996Z",
+ "status": "ACKNOWLEDGED",
+ "assignees": [{"username": "root"}]
+ },
+ {
+ "iid": "1527544",
+ "title": "SyntaxError: Invalid or unexpected token",
+ "severity": "LOW",
+ "eventCount": 4,
+ "startedAt": "2020-04-17T23:18:14.996Z",
+ "endedAt": "2020-04-17T23:18:14.996Z",
+ "status": "RESOLVED",
+ "assignees": [{"username": "root"}]
+ }
+ ]
diff --git a/spec/frontend/clusters_list/components/clusters_spec.js b/spec/frontend/clusters_list/components/clusters_spec.js
index 9f76078a69a..3a5c4c4c008 100644
--- a/spec/frontend/clusters_list/components/clusters_spec.js
+++ b/spec/frontend/clusters_list/components/clusters_spec.js
@@ -5,6 +5,7 @@ import MockAdapter from 'axios-mock-adapter';
import { apiData } from '../mock_data';
import { mount } from '@vue/test-utils';
import { GlLoadingIcon, GlTable, GlPagination } from '@gitlab/ui';
+import * as Sentry from '@sentry/browser';
describe('Clusters', () => {
let mock;
@@ -36,7 +37,11 @@ describe('Clusters', () => {
};
};
+ let captureException;
+
beforeEach(() => {
+ captureException = jest.spyOn(Sentry, 'captureException');
+
mock = new MockAdapter(axios);
mockPollingApi(200, apiData, paginationHeader());
@@ -46,6 +51,7 @@ describe('Clusters', () => {
afterEach(() => {
wrapper.destroy();
mock.restore();
+ captureException.mockRestore();
});
describe('clusters table', () => {
@@ -106,8 +112,8 @@ describe('Clusters', () => {
${'Unknown'} | ${0}
${'1'} | ${1}
${'2'} | ${2}
- ${'Unknown'} | ${3}
- ${'Unknown'} | ${4}
+ ${'1'} | ${3}
+ ${'1'} | ${4}
${'Unknown'} | ${5}
`('renders node size for each cluster', ({ nodeSize, lineNumber }) => {
const sizes = findTable().findAll('td:nth-child(3)');
@@ -115,6 +121,58 @@ describe('Clusters', () => {
expect(size.text()).toBe(nodeSize);
});
+
+ describe('nodes with unknown quantity', () => {
+ it('notifies Sentry about all missing quantity types', () => {
+ expect(captureException).toHaveBeenCalledTimes(8);
+ });
+
+ it('notifies Sentry about CPU missing quantity types', () => {
+ const missingCpuTypeError = new Error('UnknownK8sCpuQuantity:1missingCpuUnit');
+
+ expect(captureException).toHaveBeenCalledWith(missingCpuTypeError);
+ });
+
+ it('notifies Sentry about Memory missing quantity types', () => {
+ const missingMemoryTypeError = new Error('UnknownK8sMemoryQuantity:1missingMemoryUnit');
+
+ expect(captureException).toHaveBeenCalledWith(missingMemoryTypeError);
+ });
+ });
+ });
+
+ describe('cluster CPU', () => {
+ it.each`
+ clusterCpu | lineNumber
+ ${''} | ${0}
+ ${'1.93 (87% free)'} | ${1}
+ ${'3.87 (86% free)'} | ${2}
+ ${'(% free)'} | ${3}
+ ${'(% free)'} | ${4}
+ ${''} | ${5}
+ `('renders total cpu for each cluster', ({ clusterCpu, lineNumber }) => {
+ const clusterCpus = findTable().findAll('td:nth-child(4)');
+ const cpuData = clusterCpus.at(lineNumber);
+
+ expect(cpuData.text()).toBe(clusterCpu);
+ });
+ });
+
+ describe('cluster Memory', () => {
+ it.each`
+ clusterMemory | lineNumber
+ ${''} | ${0}
+ ${'5.92 (78% free)'} | ${1}
+ ${'12.86 (79% free)'} | ${2}
+ ${'(% free)'} | ${3}
+ ${'(% free)'} | ${4}
+ ${''} | ${5}
+ `('renders total memory for each cluster', ({ clusterMemory, lineNumber }) => {
+ const clusterMemories = findTable().findAll('td:nth-child(5)');
+ const memoryData = clusterMemories.at(lineNumber);
+
+ expect(memoryData.text()).toBe(clusterMemory);
+ });
});
describe('pagination', () => {
diff --git a/spec/frontend/clusters_list/mock_data.js b/spec/frontend/clusters_list/mock_data.js
index 6ce0aa90f10..eb8582796f7 100644
--- a/spec/frontend/clusters_list/mock_data.js
+++ b/spec/frontend/clusters_list/mock_data.js
@@ -11,7 +11,12 @@ export const clusterList = [
environment_scope: 'development',
cluster_type: 'project_type',
status: 'unreachable',
- nodes: [{ usage: { cpu: '246155922n', memory: '1255212Ki' } }],
+ nodes: [
+ {
+ status: { allocatable: { cpu: '1930m', memory: '5777156Ki' } },
+ usage: { cpu: '246155922n', memory: '1255212Ki' },
+ },
+ ],
},
{
name: 'My Cluster 3',
@@ -19,8 +24,14 @@ export const clusterList = [
cluster_type: 'project_type',
status: 'authentication_failure',
nodes: [
- { usage: { cpu: '246155922n', memory: '1255212Ki' } },
- { usage: { cpu: '307051934n', memory: '1379136Ki' } },
+ {
+ status: { allocatable: { cpu: '1930m', memory: '5777156Ki' } },
+ usage: { cpu: '246155922n', memory: '1255212Ki' },
+ },
+ {
+ status: { allocatable: { cpu: '1940m', memory: '6777156Ki' } },
+ usage: { cpu: '307051934n', memory: '1379136Ki' },
+ },
],
},
{
@@ -28,12 +39,23 @@ export const clusterList = [
environment_scope: 'production',
cluster_type: 'project_type',
status: 'deleting',
+ nodes: [
+ {
+ status: { allocatable: { cpu: '1missingCpuUnit', memory: '1missingMemoryUnit' } },
+ usage: { cpu: '1missingCpuUnit', memory: '1missingMemoryUnit' },
+ },
+ ],
},
{
name: 'My Cluster 5',
environment_scope: 'development',
cluster_type: 'project_type',
status: 'created',
+ nodes: [
+ {
+ status: { allocatable: { cpu: '1missingCpuUnit', memory: '1missingMemoryUnit' } },
+ },
+ ],
},
{
name: 'My Cluster 6',
diff --git a/spec/graphql/resolvers/alert_management/alerts/assignees_resolver_spec.rb b/spec/graphql/resolvers/alert_management/alerts/assignees_resolver_spec.rb
deleted file mode 100644
index d18c828b191..00000000000
--- a/spec/graphql/resolvers/alert_management/alerts/assignees_resolver_spec.rb
+++ /dev/null
@@ -1,32 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-describe Resolvers::AlertManagement::Alerts::AssigneesResolver do
- include GraphqlHelpers
-
- describe '#resolve' do
- let_it_be(:current_user) { create(:user) }
- let_it_be(:project) { create(:project) }
- let_it_be(:alert) { create(:alert_management_alert, :all_fields, project: project) }
- let_it_be(:another_alert) { create(:alert_management_alert, :all_fields, project: project) }
-
- it 'resolves for a single alert' do
- result = batch_sync(max_queries: 2) { resolve_assignees(alert) }
-
- expect(result).to match_array(alert.assignees)
- end
-
- it 'resolves for multiple alerts' do
- result = batch_sync(max_queries: 2) { [resolve_assignees(alert), resolve_assignees(another_alert)] }
-
- expect(result).to match_array([alert.assignees, another_alert.assignees])
- end
-
- private
-
- def resolve_assignees(alert, args = {}, context = { current_user: current_user })
- resolve(described_class, obj: alert, args: args, ctx: context)
- end
- end
-end
diff --git a/spec/lib/gitlab/ci/yaml_processor_spec.rb b/spec/lib/gitlab/ci/yaml_processor_spec.rb
index c93bb901981..1668149d8f5 100644
--- a/spec/lib/gitlab/ci/yaml_processor_spec.rb
+++ b/spec/lib/gitlab/ci/yaml_processor_spec.rb
@@ -1388,7 +1388,7 @@ module Gitlab
let(:processor) { Gitlab::Ci::YamlProcessor.new(YAML.dump(config)) }
let(:config) do
{
- stages: ["build", "test", "release"], # rubocop:disable Style/WordArray
+ stages: %w[build test release],
release: {
stage: "release",
only: ["tags"],
diff --git a/spec/lib/gitlab/git_access_project_spec.rb b/spec/lib/gitlab/git_access_project_spec.rb
new file mode 100644
index 00000000000..f7f7976ccb8
--- /dev/null
+++ b/spec/lib/gitlab/git_access_project_spec.rb
@@ -0,0 +1,166 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::GitAccessProject do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:project) { create(:project, :repository) }
+ let(:actor) { user }
+ let(:project_path) { project.path }
+ let(:namespace_path) { project&.namespace&.path }
+ let(:protocol) { 'ssh' }
+ let(:authentication_abilities) { %i[read_project download_code push_code] }
+ let(:changes) { Gitlab::GitAccess::ANY }
+ let(:push_access_check) { access.check('git-receive-pack', changes) }
+ let(:pull_access_check) { access.check('git-upload-pack', changes) }
+
+ describe '#check_project_accessibility!' do
+ context 'when the project is nil' do
+ let(:project) { nil }
+ let(:project_path) { "new-project" }
+
+ context 'when user is allowed to create project in namespace' do
+ let(:namespace_path) { user.namespace.path }
+ let(:access) do
+ described_class.new(actor, nil,
+ protocol, authentication_abilities: authentication_abilities,
+ repository_path: project_path, namespace_path: namespace_path)
+ end
+
+ it 'blocks pull access with "not found"' do
+ expect { pull_access_check }.to raise_not_found
+ end
+
+ it 'allows push access' do
+ expect { push_access_check }.not_to raise_error
+ end
+ end
+
+ context 'when user is not allowed to create project in namespace' do
+ let(:user2) { create(:user) }
+ let(:namespace_path) { user2.namespace.path }
+ let(:access) do
+ described_class.new(actor, nil,
+ protocol, authentication_abilities: authentication_abilities,
+ repository_path: project_path, namespace_path: namespace_path)
+ end
+
+ it 'blocks push and pull with "not found"' do
+ aggregate_failures do
+ expect { pull_access_check }.to raise_not_found
+ expect { push_access_check }.to raise_not_found
+ end
+ end
+ end
+ end
+ end
+
+ describe '#ensure_project_on_push!' do
+ let(:access) do
+ described_class.new(actor, project,
+ protocol, authentication_abilities: authentication_abilities,
+ repository_path: project_path, namespace_path: namespace_path)
+ end
+
+ before do
+ allow(access).to receive(:changes).and_return(changes)
+ end
+
+ context 'when push' do
+ let(:cmd) { 'git-receive-pack' }
+
+ context 'when project does not exist' do
+ let(:project_path) { "nonexistent" }
+ let(:project) { nil }
+
+ context 'when changes is _any' do
+ let(:changes) { Gitlab::GitAccess::ANY }
+
+ context 'when authentication abilities include push code' do
+ let(:authentication_abilities) { [:push_code] }
+
+ context 'when user can create project in namespace' do
+ let(:namespace_path) { user.namespace.path }
+
+ it 'creates a new project' do
+ expect { access.send(:ensure_project_on_push!, cmd) }
+ .to change { Project.count }.by(1)
+ .and change { Project.where(namespace: user.namespace, name: project_path).count }.by(1)
+ end
+ end
+
+ context 'when user cannot create project in namespace' do
+ let(:user2) { create(:user) }
+ let(:namespace_path) { user2.namespace.path }
+
+ it 'does not create a new project' do
+ expect { access.send(:ensure_project_on_push!, cmd) }.not_to change { Project.count }
+ end
+ end
+ end
+
+ context 'when authentication abilities do not include push code' do
+ let(:authentication_abilities) { [] }
+
+ context 'when user can create project in namespace' do
+ let(:namespace_path) { user.namespace.path }
+
+ it 'does not create a new project' do
+ expect { access.send(:ensure_project_on_push!, cmd) }.not_to change { Project.count }
+ end
+ end
+ end
+ end
+
+ context 'when check contains actual changes' do
+ let(:changes) { "#{Gitlab::Git::BLANK_SHA} 570e7b2abdd848b95f2f578043fc23bd6f6fd24d refs/heads/new_branch" }
+
+ it 'does not create a new project' do
+ expect { access.send(:ensure_project_on_push!, cmd) }.not_to change { Project.count }
+ end
+ end
+ end
+
+ context 'when project exists' do
+ let(:changes) { Gitlab::GitAccess::ANY }
+ let!(:project) { create(:project) }
+
+ it 'does not create a new project' do
+ expect { access.send(:ensure_project_on_push!, cmd) }.not_to change { Project.count }
+ end
+ end
+
+ context 'when deploy key is used' do
+ let(:key) { create(:deploy_key, user: user) }
+ let(:actor) { key }
+ let(:project_path) { "nonexistent" }
+ let(:project) { nil }
+ let(:namespace_path) { user.namespace.path }
+ let(:changes) { Gitlab::GitAccess::ANY }
+
+ it 'does not create a new project' do
+ expect { access.send(:ensure_project_on_push!, cmd) }.not_to change { Project.count }
+ end
+ end
+ end
+
+ context 'when pull' do
+ let(:cmd) { 'git-upload-pack' }
+ let(:changes) { Gitlab::GitAccess::ANY }
+
+ context 'when project does not exist' do
+ let(:project_path) { "new-project" }
+ let(:namespace_path) { user.namespace.path }
+ let(:project) { nil }
+
+ it 'does not create a new project' do
+ expect { access.send(:ensure_project_on_push!, cmd) }.not_to change { Project.count }
+ end
+ end
+ end
+ end
+
+ def raise_not_found
+ raise_error(Gitlab::GitAccess::NotFoundError, Gitlab::GitAccess::ERROR_MESSAGES[:project_not_found])
+ end
+end
diff --git a/spec/lib/gitlab/git_access_spec.rb b/spec/lib/gitlab/git_access_spec.rb
index 55526241673..7c09fc5cc79 100644
--- a/spec/lib/gitlab/git_access_spec.rb
+++ b/spec/lib/gitlab/git_access_spec.rb
@@ -228,40 +228,12 @@ describe Gitlab::GitAccess do
context 'when the project is nil' do
let(:project) { nil }
let(:project_path) { "new-project" }
+ let(:namespace_path) { user.namespace.path }
- context 'when user is allowed to create project in namespace' do
- let(:namespace_path) { user.namespace.path }
- let(:access) do
- described_class.new(actor, nil,
- protocol, authentication_abilities: authentication_abilities,
- repository_path: project_path, namespace_path: namespace_path,
- redirected_path: redirected_path)
- end
-
- it 'blocks pull access with "not found"' do
+ it 'blocks push and pull with "not found"' do
+ aggregate_failures do
expect { pull_access_check }.to raise_not_found
- end
-
- it 'allows push access' do
- expect { push_access_check }.not_to raise_error
- end
- end
-
- context 'when user is not allowed to create project in namespace' do
- let(:user2) { create(:user) }
- let(:namespace_path) { user2.namespace.path }
- let(:access) do
- described_class.new(actor, nil,
- protocol, authentication_abilities: authentication_abilities,
- repository_path: project_path, namespace_path: namespace_path,
- redirected_path: redirected_path)
- end
-
- it 'blocks push and pull with "not found"' do
- aggregate_failures do
- expect { pull_access_check }.to raise_not_found
- expect { push_access_check }.to raise_not_found
- end
+ expect { push_access_check }.to raise_not_found
end
end
end
@@ -443,106 +415,6 @@ describe Gitlab::GitAccess do
end
end
- describe '#ensure_project_on_push!' do
- let(:access) do
- described_class.new(actor, project,
- protocol, authentication_abilities: authentication_abilities,
- repository_path: project_path, namespace_path: namespace_path,
- redirected_path: redirected_path)
- end
-
- context 'when push' do
- let(:cmd) { 'git-receive-pack' }
-
- context 'when project does not exist' do
- let(:project_path) { "nonexistent" }
- let(:project) { nil }
-
- context 'when changes is _any' do
- let(:changes) { Gitlab::GitAccess::ANY }
-
- context 'when authentication abilities include push code' do
- let(:authentication_abilities) { [:push_code] }
-
- context 'when user can create project in namespace' do
- let(:namespace_path) { user.namespace.path }
-
- it 'creates a new project' do
- expect { access.send(:ensure_project_on_push!, cmd, changes) }.to change { Project.count }.by(1)
- end
- end
-
- context 'when user cannot create project in namespace' do
- let(:user2) { create(:user) }
- let(:namespace_path) { user2.namespace.path }
-
- it 'does not create a new project' do
- expect { access.send(:ensure_project_on_push!, cmd, changes) }.not_to change { Project.count }
- end
- end
- end
-
- context 'when authentication abilities do not include push code' do
- let(:authentication_abilities) { [] }
-
- context 'when user can create project in namespace' do
- let(:namespace_path) { user.namespace.path }
-
- it 'does not create a new project' do
- expect { access.send(:ensure_project_on_push!, cmd, changes) }.not_to change { Project.count }
- end
- end
- end
- end
-
- context 'when check contains actual changes' do
- let(:changes) { "#{Gitlab::Git::BLANK_SHA} 570e7b2abdd848b95f2f578043fc23bd6f6fd24d refs/heads/new_branch" }
-
- it 'does not create a new project' do
- expect { access.send(:ensure_project_on_push!, cmd, changes) }.not_to change { Project.count }
- end
- end
- end
-
- context 'when project exists' do
- let(:changes) { Gitlab::GitAccess::ANY }
- let!(:project) { create(:project) }
-
- it 'does not create a new project' do
- expect { access.send(:ensure_project_on_push!, cmd, changes) }.not_to change { Project.count }
- end
- end
-
- context 'when deploy key is used' do
- let(:key) { create(:deploy_key, user: user) }
- let(:actor) { key }
- let(:project_path) { "nonexistent" }
- let(:project) { nil }
- let(:namespace_path) { user.namespace.path }
- let(:changes) { Gitlab::GitAccess::ANY }
-
- it 'does not create a new project' do
- expect { access.send(:ensure_project_on_push!, cmd, changes) }.not_to change { Project.count }
- end
- end
- end
-
- context 'when pull' do
- let(:cmd) { 'git-upload-pack' }
- let(:changes) { Gitlab::GitAccess::ANY }
-
- context 'when project does not exist' do
- let(:project_path) { "new-project" }
- let(:namespace_path) { user.namespace.path }
- let(:project) { nil }
-
- it 'does not create a new project' do
- expect { access.send(:ensure_project_on_push!, cmd, changes) }.not_to change { Project.count }
- end
- end
- end
- end
-
describe '#check_download_access!' do
it 'allows maintainers to pull' do
project.add_maintainer(user)
diff --git a/spec/lib/gitlab/graphql/loaders/alert_management/alerts/assignees_loader_spec.rb b/spec/lib/gitlab/graphql/loaders/alert_management/alerts/assignees_loader_spec.rb
deleted file mode 100644
index e4f5ad324ba..00000000000
--- a/spec/lib/gitlab/graphql/loaders/alert_management/alerts/assignees_loader_spec.rb
+++ /dev/null
@@ -1,44 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-describe Gitlab::Graphql::Loaders::AlertManagement::Alerts::AssigneesLoader do
- describe '#find' do
- let_it_be(:user) { create(:user) }
- let_it_be(:project) { create(:project) }
- let_it_be(:alert1) { create(:alert_management_alert, project: project, assignees: [user]) }
- let_it_be(:alert2) { create(:alert_management_alert, :all_fields, project: project) }
- let_it_be(:alert3) { create(:alert_management_alert, project: project) }
- let(:filter) { proc {} }
-
- subject do
- [
- described_class.new(alert1.id, filter).find,
- described_class.new(alert2.id, filter).find,
- described_class.new(alert3.id, filter).find
- ].map(&:sync)
- end
-
- it 'only queries once for alert assignees' do
- # One query for alert_assignees, one query for users
- expect { subject }.not_to exceed_query_limit(2)
- end
-
- it 'returns appropriate assignees for alerts' do
- expect(subject).to eq [alert1.assignees.to_a, alert2.assignees.to_a, alert3.assignees.to_a]
- end
-
- context 'with a filter' do
- let(:filter) { proc { |users| users.select { |u| u == user } } }
-
- it 'limits assignees by the filter' do
- expect(subject).to eq [alert1.assignees.to_a, alert2.assignees.to_a, alert3.assignees.to_a]
- expect(subject.all?(Gitlab::Graphql::FilterableArray)).to be_truthy
-
- filtered_result = subject.map { |assignees| assignees.filter_callback.call(assignees) }
-
- expect(filtered_result).to eq [[user], [], []]
- end
- end
- end
-end
diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml
index 432190b4318..88d5a01072f 100644
--- a/spec/lib/gitlab/import_export/all_models.yml
+++ b/spec/lib/gitlab/import_export/all_models.yml
@@ -481,6 +481,7 @@ project:
- upstream_project_subscriptions
- downstream_project_subscriptions
- service_desk_setting
+- security_setting
- import_failures
- container_expiration_policy
- resource_groups
diff --git a/spec/lib/gitlab/import_export/import_test_coverage_spec.rb b/spec/lib/gitlab/import_export/import_test_coverage_spec.rb
index 4913984e5dc..c5a7327332e 100644
--- a/spec/lib/gitlab/import_export/import_test_coverage_spec.rb
+++ b/spec/lib/gitlab/import_export/import_test_coverage_spec.rb
@@ -51,6 +51,7 @@ describe 'Test coverage of the Project Import' do
project.metrics_setting
project.boards.lists.label.priorities
project.service_desk_setting
+ project.security_setting
].freeze
end
diff --git a/spec/lib/gitlab/import_export/safe_model_attributes.yml b/spec/lib/gitlab/import_export/safe_model_attributes.yml
index aa2dfe26caa..97fd30837d4 100644
--- a/spec/lib/gitlab/import_export/safe_model_attributes.yml
+++ b/spec/lib/gitlab/import_export/safe_model_attributes.yml
@@ -864,3 +864,11 @@ SystemNoteMetadata:
- action
- created_at
- updated_at
+ProjectSecuritySetting:
+ - project_id
+ - auto_fix_container_scanning
+ - auto_fix_dast
+ - auto_fix_dependency_scanning
+ - auto_fix_sast
+ - created_at
+ - updated_at
diff --git a/spec/models/alert_management/alert_assignee_spec.rb b/spec/models/alert_management/alert_assignee_spec.rb
index 367469c7d47..c51a5d543ab 100644
--- a/spec/models/alert_management/alert_assignee_spec.rb
+++ b/spec/models/alert_management/alert_assignee_spec.rb
@@ -3,37 +3,19 @@
require 'spec_helper'
describe AlertManagement::AlertAssignee do
- let_it_be(:user1) { create(:user) }
- let_it_be(:user2) { create(:user) }
- let_it_be(:alert1) { create(:alert_management_alert, assignees: [user1, user2]) }
- let_it_be(:alert2) { create(:alert_management_alert, assignees: [user2]) }
-
describe 'associations' do
it { is_expected.to belong_to(:alert) }
it { is_expected.to belong_to(:assignee) }
end
describe 'validations' do
- subject { alert1.alert_assignees.build(assignee: user1) }
+ let(:alert) { create(:alert_management_alert) }
+ let(:user) { create(:user) }
+
+ subject { alert.alert_assignees.build(assignee: user) }
it { is_expected.to validate_presence_of(:alert) }
it { is_expected.to validate_presence_of(:assignee) }
it { is_expected.to validate_uniqueness_of(:assignee).scoped_to(:alert_id) }
end
-
- describe 'scopes' do
- describe '.for_alert_ids' do
- let(:alert_ids) { alert1.id }
-
- subject { described_class.for_alert_ids(alert_ids) }
-
- it { is_expected.to contain_exactly(*alert1.reload.alert_assignees) }
-
- context 'with multiple ids' do
- let(:alert_ids) { [alert1.id, alert2.id] }
-
- it { is_expected.to contain_exactly(*alert1.reload.alert_assignees, *alert2.reload.alert_assignees) }
- end
- end
- end
end
diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb
index 59c536d6831..b5cf832b898 100644
--- a/spec/models/ci/pipeline_spec.rb
+++ b/spec/models/ci/pipeline_spec.rb
@@ -2749,6 +2749,30 @@ describe Ci::Pipeline, :mailer do
end
end
+ describe '#latest_report_builds' do
+ it 'returns build with test artifacts' do
+ test_build = create(:ci_build, :test_reports, pipeline: pipeline, project: project)
+ coverage_build = create(:ci_build, :coverage_reports, pipeline: pipeline, project: project)
+ create(:ci_build, :artifacts, pipeline: pipeline, project: project)
+
+ expect(pipeline.latest_report_builds).to contain_exactly(test_build, coverage_build)
+ end
+
+ it 'filters builds by scope' do
+ test_build = create(:ci_build, :test_reports, pipeline: pipeline, project: project)
+ create(:ci_build, :coverage_reports, pipeline: pipeline, project: project)
+
+ expect(pipeline.latest_report_builds(Ci::JobArtifact.test_reports)).to contain_exactly(test_build)
+ end
+
+ it 'only returns not retried builds' do
+ test_build = create(:ci_build, :test_reports, pipeline: pipeline, project: project)
+ create(:ci_build, :test_reports, :retried, pipeline: pipeline, project: project)
+
+ expect(pipeline.latest_report_builds).to contain_exactly(test_build)
+ end
+ end
+
describe '#has_reports?' do
subject { pipeline.has_reports?(Ci::JobArtifact.test_reports) }
diff --git a/spec/models/clusters/cluster_spec.rb b/spec/models/clusters/cluster_spec.rb
index 1b9f697a071..8dbbe42a29f 100644
--- a/spec/models/clusters/cluster_spec.rb
+++ b/spec/models/clusters/cluster_spec.rb
@@ -1057,7 +1057,7 @@ describe Clusters::Cluster, :use_clean_rails_memory_store_caching do
.and_raise(SocketError)
end
- it { is_expected.to eq(connection_status: :unreachable, nodes: []) }
+ it { is_expected.to eq(connection_status: :unreachable, nodes: nil) }
end
context 'cluster cannot be authenticated to' do
@@ -1066,7 +1066,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, nodes: []) }
+ it { is_expected.to eq(connection_status: :authentication_failure, nodes: nil) }
end
describe 'Kubeclient::HttpError' do
@@ -1078,18 +1078,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, nodes: []) }
+ it { is_expected.to eq(connection_status: :authentication_failure, nodes: nil) }
context 'generic timeout' do
let(:error_message) { 'Timed out connecting to server'}
- it { is_expected.to eq(connection_status: :unreachable, nodes: []) }
+ it { is_expected.to eq(connection_status: :unreachable, nodes: nil) }
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, nodes: []) }
+ it { is_expected.to eq(connection_status: :unreachable, nodes: nil) }
end
end
@@ -1099,7 +1099,7 @@ describe Clusters::Cluster, :use_clean_rails_memory_store_caching do
.and_raise(StandardError)
end
- it { is_expected.to eq(connection_status: :unknown_failure, nodes: []) }
+ it { is_expected.to eq(connection_status: :unknown_failure, nodes: nil) }
it 'notifies Sentry' do
expect(Gitlab::ErrorTracking).to receive(:track_exception)
diff --git a/spec/requests/api/graphql/project/alert_management/alert/assignees_spec.rb b/spec/requests/api/graphql/project/alert_management/alert/assignees_spec.rb
deleted file mode 100644
index 86b56e42a24..00000000000
--- a/spec/requests/api/graphql/project/alert_management/alert/assignees_spec.rb
+++ /dev/null
@@ -1,85 +0,0 @@
-# frozen_string_literal: true
-require 'spec_helper'
-
-describe 'getting Alert Management Alert Assignees' do
- include GraphqlHelpers
-
- let_it_be(:project) { create(:project) }
- let_it_be(:current_user) { create(:user) }
- let_it_be(:first_alert) { create(:alert_management_alert, project: project, assignees: [current_user]) }
- let_it_be(:second_alert) { create(:alert_management_alert, project: project) }
-
- let(:params) { {} }
-
- let(:fields) do
- <<~QUERY
- nodes {
- #{all_graphql_fields_for('AlertManagementAlert')}
- }
- QUERY
- end
-
- let(:query) do
- graphql_query_for(
- 'project',
- { 'fullPath' => project.full_path },
- query_graphql_field('alertManagementAlerts', params, fields)
- )
- end
-
- let(:alerts) { graphql_data.dig('project', 'alertManagementAlerts', 'nodes') }
- let(:assignees) { alerts.map { |alert| [alert['iid'], alert['assignees']['nodes']] }.to_h }
- let(:first_assignees) { assignees[first_alert.iid.to_s] }
- let(:second_assignees) { assignees[second_alert.iid.to_s] }
-
- before do
- project.add_developer(current_user)
- end
-
- it 'returns the correct assignees' do
- post_graphql(query, current_user: current_user)
-
- expect(first_assignees.length).to eq(1)
- expect(first_assignees.first).to include('username' => current_user.username)
- expect(second_assignees).to be_empty
- end
-
- it 'applies appropriate filters for non-visible users' do
- allow(Ability).to receive(:allowed?).and_call_original
- allow(Ability).to receive(:allowed?).with(current_user, :read_user, current_user).and_return(false)
-
- post_graphql(query, current_user: current_user)
-
- expect(first_assignees).to be_empty
- expect(second_assignees).to be_empty
- end
-
- it 'avoids N+1 queries' do
- base_count = ActiveRecord::QueryRecorder.new do
- post_graphql(query, current_user: current_user)
- end
-
- # An N+1 would mean a new alert would increase the query count
- third_alert = create(:alert_management_alert, project: project, assignees: [current_user])
-
- expect { post_graphql(query, current_user: current_user) }.not_to exceed_query_limit(base_count)
-
- third_assignees = assignees[third_alert.iid.to_s]
-
- expect(third_assignees.length).to eq(1)
- expect(third_assignees.first).to include('username' => current_user.username)
- end
-
- context 'with alert_assignee flag disabled' do
- before do
- stub_feature_flags(alert_assignee: false)
- end
-
- it 'excludes assignees' do
- post_graphql(query, current_user: current_user)
-
- expect(first_assignees).to be_empty
- expect(second_assignees).to be_empty
- end
- end
-end
diff --git a/spec/requests/api/graphql/project/alert_management/alerts_spec.rb b/spec/requests/api/graphql/project/alert_management/alerts_spec.rb
index 05c1eb732ef..ae819f93ee7 100644
--- a/spec/requests/api/graphql/project/alert_management/alerts_spec.rb
+++ b/spec/requests/api/graphql/project/alert_management/alerts_spec.rb
@@ -75,7 +75,7 @@ describe 'getting Alert Management Alerts' do
'updatedAt' => triggered_alert.updated_at.strftime('%Y-%m-%dT%H:%M:%SZ')
)
- expect(first_alert['assignees']['nodes'].first).to include('username' => triggered_alert.assignees.first.username)
+ expect(first_alert['assignees'].first).to include('username' => triggered_alert.assignees.first.username)
expect(second_alert).to include(
'iid' => resolved_alert.iid.to_s,
@@ -137,5 +137,18 @@ describe 'getting Alert Management Alerts' do
end
end
end
+
+ context 'with alert_assignee flag disabled' do
+ before do
+ stub_feature_flags(alert_assignee: false)
+ project.add_developer(current_user)
+
+ post_graphql(query, current_user: current_user)
+ end
+
+ it 'excludes assignees' do
+ expect(alerts.first['assignees']).to be_empty
+ end
+ end
end
end