diff --git a/app/controllers/projects/environments_controller.rb b/app/controllers/projects/environments_controller.rb index 23dabd885c8..84ebdcd9364 100644 --- a/app/controllers/projects/environments_controller.rb +++ b/app/controllers/projects/environments_controller.rb @@ -70,11 +70,9 @@ class Projects::EnvironmentsController < Projects::ApplicationController end # rubocop: enable CodeReuse/ActiveRecord - # rubocop: disable CodeReuse/ActiveRecord def show - @deployments = environment.deployments.order(id: :desc).page(params[:page]) + @deployments = environment.deployments.ordered.page(params[:page]) end - # rubocop: enable CodeReuse/ActiveRecord def new @environment = project.environments.new diff --git a/app/controllers/projects/usage_quotas_controller.rb b/app/controllers/projects/usage_quotas_controller.rb index 103e1cc596a..b319e427eaa 100644 --- a/app/controllers/projects/usage_quotas_controller.rb +++ b/app/controllers/projects/usage_quotas_controller.rb @@ -2,7 +2,6 @@ class Projects::UsageQuotasController < Projects::ApplicationController before_action :authorize_admin_project! - before_action :verify_usage_quotas_enabled! layout "project_settings" @@ -20,10 +19,4 @@ class Projects::UsageQuotasController < Projects::ApplicationController wiki_help_page_path: help_page_path('administration/wikis/index.md', anchor: 'reduce-wiki-repository-size') } end - - private - - def verify_usage_quotas_enabled! - render_404 unless Feature.enabled?(:project_storage_ui, project&.group, default_enabled: :yaml) - end end diff --git a/app/models/deployment.rb b/app/models/deployment.rb index f91700f764b..140d4fefd90 100644 --- a/app/models/deployment.rb +++ b/app/models/deployment.rb @@ -54,6 +54,8 @@ class Deployment < ApplicationRecord scope :finished_after, ->(date) { where('finished_at >= ?', date) } scope :finished_before, ->(date) { where('finished_at < ?', date) } + scope :ordered, -> { order(finished_at: :desc) } + FINISHED_STATUSES = %i[success failed canceled].freeze state_machine :status, initial: :created do diff --git a/app/views/projects/deployments/_deployment.html.haml b/app/views/projects/deployments/_deployment.html.haml index 57dfcb8cf4a..f18574c3ad5 100644 --- a/app/views/projects/deployments/_deployment.html.haml +++ b/app/views/projects/deployments/_deployment.html.haml @@ -6,7 +6,7 @@ .table-section.section-10{ role: 'gridcell' } .table-mobile-header{ role: 'rowheader' }= _("ID") - %strong.table-mobile-content ##{deployment.iid} + %strong.table-mobile-content{ data: { testid: 'deployment-id' } } ##{deployment.iid} .table-section.section-10{ role: 'gridcell' } .table-mobile-header{ role: 'rowheader' }= _("Triggerer") diff --git a/config/feature_flags/development/project_storage_ui.yml b/config/feature_flags/development/project_storage_ui.yml deleted file mode 100644 index 23a5b5c3d29..00000000000 --- a/config/feature_flags/development/project_storage_ui.yml +++ /dev/null @@ -1,8 +0,0 @@ ---- -name: project_storage_ui -introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68289 -rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/334889 -milestone: '14.2' -type: development -group: group::utilization -default_enabled: false diff --git a/doc/administration/geo/setup/database.md b/doc/administration/geo/setup/database.md index d72bb0737ae..7372cc4ce15 100644 --- a/doc/administration/geo/setup/database.md +++ b/doc/administration/geo/setup/database.md @@ -7,23 +7,21 @@ type: howto # Geo database replication **(PREMIUM SELF)** -NOTE: -If your GitLab installation uses external (not managed by Omnibus) PostgreSQL -instances, the Omnibus roles are unable to perform all necessary -configuration steps. In this case, -[follow the Geo with external PostgreSQL instances document instead](external_database.md). +This document describes the minimal required steps to replicate your primary +GitLab database to a secondary node's database. You may have to change some +values, based on attributes including your database's setup and size. NOTE: +If your GitLab installation uses external (not managed by Omnibus GitLab) +PostgreSQL instances, the Omnibus roles cannot perform all necessary +configuration steps. In this case, use the [Geo with external PostgreSQL instances](external_database.md) +process instead. + The stages of the setup process must be completed in the documented order. -Before attempting the steps in this stage, [complete all prior stages](../setup/index.md#using-omnibus-gitlab). +Before you attempt the steps in this stage, [complete all prior stages](../setup/index.md#using-omnibus-gitlab). -This document describes the minimal steps you have to take to replicate your -**primary** GitLab database to a **secondary** node's database. You may have to -change some values, based on attributes including your database's setup and -size. - -You are encouraged to first read through all the steps before executing them -in your testing/production environment. +Be sure to read and review all of these steps before you execute them in your +testing or production environments. ## Single instance database replication @@ -214,7 +212,7 @@ There is an [issue where support is being discussed](https://gitlab.com/gitlab-o ## - Prevents automatic upgrade of Postgres since it requires downtime of ## streaming replication to Geo secondary sites ## - Enables standard single-node GitLab services like NGINX, Puma, Redis, - ## Sidekiq, etc. If you are segregating services, then you will need to + ## or Sidekiq. If you are segregating services, then you will need to ## explicitly disable unwanted services. ## roles(['geo_primary_role']) diff --git a/doc/development/contributing/merge_request_workflow.md b/doc/development/contributing/merge_request_workflow.md index a521d89db2b..91643cd3ee0 100644 --- a/doc/development/contributing/merge_request_workflow.md +++ b/doc/development/contributing/merge_request_workflow.md @@ -240,6 +240,7 @@ requirements. 1. Working and clean code that is commented where needed. 1. [Unit, integration, and system tests](../testing_guide/index.md) that all pass on the CI server. +1. Peer member testing is optional but recommended when the risk of a change is high. This includes when the changes are [far-reaching](https://about.gitlab.com/handbook/engineering/development/#reducing-the-impact-of-far-reaching-work) or are for [components critical for security](../code_review.md#security). 1. Regressions and bugs are covered with tests that reduce the risk of the issue happening again. 1. [Performance guidelines](../merge_request_performance_guidelines.md) have been followed. diff --git a/doc/install/aws/eks_clusters_aws.md b/doc/install/aws/eks_clusters_aws.md index 3c19a83f128..86318467a91 100644 --- a/doc/install/aws/eks_clusters_aws.md +++ b/doc/install/aws/eks_clusters_aws.md @@ -1,7 +1,6 @@ --- -type: reference, concepts stage: Enablement -group: Alliances +group: Distribution info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments --- diff --git a/doc/install/aws/gitlab_hybrid_on_aws.md b/doc/install/aws/gitlab_hybrid_on_aws.md index 4d22a29ad0a..1fe183629b3 100644 --- a/doc/install/aws/gitlab_hybrid_on_aws.md +++ b/doc/install/aws/gitlab_hybrid_on_aws.md @@ -1,7 +1,6 @@ --- -type: reference, concepts stage: Enablement -group: Alliances +group: Distribution info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments --- diff --git a/doc/install/aws/gitlab_sre_for_aws.md b/doc/install/aws/gitlab_sre_for_aws.md index 06e3bf784bd..3365888a8ea 100644 --- a/doc/install/aws/gitlab_sre_for_aws.md +++ b/doc/install/aws/gitlab_sre_for_aws.md @@ -1,10 +1,9 @@ --- stage: Enablement -group: Alliances +group: Distribution info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments comments: false description: Doing SRE for GitLab instances and runners on AWS. -type: index --- # GitLab Site Reliability Engineering for AWS **(FREE SELF)** diff --git a/doc/user/project/integrations/img/zentao_product_id.png b/doc/user/project/integrations/img/zentao_product_id.png new file mode 100644 index 00000000000..a91b4c3f82d Binary files /dev/null and b/doc/user/project/integrations/img/zentao_product_id.png differ diff --git a/doc/user/project/integrations/overview.md b/doc/user/project/integrations/overview.md index 2c154467115..819c17c12fd 100644 --- a/doc/user/project/integrations/overview.md +++ b/doc/user/project/integrations/overview.md @@ -62,6 +62,7 @@ Click on the service links to see further configuration instructions and details | [Unify Circuit](unify_circuit.md) | Send notifications about project events to Unify Circuit. | **{dotted-circle}** No | | [Webex Teams](webex_teams.md) | Receive events notifications. | **{dotted-circle}** No | | [YouTrack](youtrack.md) | Use YouTrack as the issue tracker. | **{dotted-circle}** No | +| [ZenTao](zentao.md) | Use ZenTao as the issue tracker. | **{dotted-circle}** No | ## Push hooks limit diff --git a/doc/user/project/integrations/zentao.md b/doc/user/project/integrations/zentao.md new file mode 100644 index 00000000000..ab8a7829139 --- /dev/null +++ b/doc/user/project/integrations/zentao.md @@ -0,0 +1,40 @@ +--- +stage: Ecosystem +group: Integrations +info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments +--- + +# ZenTao product integration **(PREMIUM)** + +[ZenTao](https://www.zentao.net/) is a web-based project management platform. + +## Configure ZenTao + +This integration requires a ZenTao API secret key. + +Complete these steps in ZenTao: + +1. Go to your **Admin** page and select **Develop > Application**. +1. Select **Add Application**. +1. Under **Name** and **Code**, enter a name and a code for the new secret key. +1. Under **Account**, select an existing account name. +1. Select **Save**. +1. Copy the generated key to use in GitLab. + +## Configure GitLab + +Complete these steps in GitLab: + +1. Go to your project and select **Settings > Integrations**. +1. Select **ZenTao**. +1. Turn on the **Active** toggle under **Enable Integration**. +1. Provide the ZenTao configuration information: + - **ZenTao Web URL**: The base URL of the ZenTao instance web interface you're linking to this GitLab project (for example, `example.zentao.net`). + - **ZenTao API URL** (optional): The base URL to the ZenTao instance API. Defaults to the Web URL value if not set. + - **ZenTao API token**: Use the key you generated when you [configured ZenTao](#configure-zentao). + - **ZenTao Product ID**: To display issues from a single ZenTao product in a given GitLab project. The Product ID can be found in the ZenTao product page under **Settings > Overview**. + + ![ZenTao settings page](img/zentao_product_id.png) + +1. To verify the ZenTao connection is working, select **Test settings**. +1. Select **Save changes**. diff --git a/doc/user/usage_quotas.md b/doc/user/usage_quotas.md index 5a48353c9d4..16b6424b232 100644 --- a/doc/user/usage_quotas.md +++ b/doc/user/usage_quotas.md @@ -36,9 +36,8 @@ namespace to recalculate the storage. > - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68898) project-level graph in GitLab 14.4 [with a flag](../administration/feature_flags.md) named `project_storage_ui`. Disabled by default. > - Enabled on GitLab.com in GitLab 14.4. - -FLAG: -On self-managed GitLab, by default this feature is not available. To make it available, ask an administrator to [enable the feature flag](../administration/feature_flags.md) named `project_storage_ui`. On GitLab.com, this feature is available. +> - Enabled on self-managed in GitLab 14.5. +> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/71270) in GitLab 14.5. The following storage usage statistics are available to an owner: diff --git a/lib/gitlab/gitaly_client.rb b/lib/gitlab/gitaly_client.rb index 2c26da037da..a824f97e197 100644 --- a/lib/gitlab/gitaly_client.rb +++ b/lib/gitlab/gitaly_client.rb @@ -24,7 +24,6 @@ module Gitlab end end - PEM_REGEX = /\-+BEGIN CERTIFICATE\-+.+?\-+END CERTIFICATE\-+/m.freeze SERVER_VERSION_FILE = 'GITALY_SERVER_VERSION' MAXIMUM_GITALY_CALLS = 30 CLIENT_NAME = (Gitlab::Runtime.sidekiq? ? 'gitlab-sidekiq' : 'gitlab-web').freeze @@ -62,28 +61,9 @@ module Gitlab end private_class_method :channel_args - def self.stub_cert_paths - cert_paths = Dir["#{OpenSSL::X509::DEFAULT_CERT_DIR}/*"] - cert_paths << OpenSSL::X509::DEFAULT_CERT_FILE if File.exist? OpenSSL::X509::DEFAULT_CERT_FILE - cert_paths - end - - def self.stub_certs - return @certs if @certs - - @certs = stub_cert_paths.flat_map do |cert_file| - File.read(cert_file).scan(PEM_REGEX).map do |cert| - OpenSSL::X509::Certificate.new(cert).to_pem - rescue OpenSSL::OpenSSLError => e - Gitlab::ErrorTracking.track_and_raise_for_dev_exception(e, cert_file: cert_file) - nil - end.compact - end.uniq.join("\n") - end - def self.stub_creds(storage) if URI(address(storage)).scheme == 'tls' - GRPC::Core::ChannelCredentials.new stub_certs + GRPC::Core::ChannelCredentials.new ::Gitlab::X509::Certificate.ca_certs_bundle else :this_channel_is_insecure end diff --git a/lib/gitlab/spamcheck/client.rb b/lib/gitlab/spamcheck/client.rb index df6d3eb7d0a..b8c07c0c316 100644 --- a/lib/gitlab/spamcheck/client.rb +++ b/lib/gitlab/spamcheck/client.rb @@ -5,6 +5,7 @@ module Gitlab module Spamcheck class Client include ::Spam::SpamConstants + DEFAULT_TIMEOUT_SECS = 2 VERDICT_MAPPING = { @@ -27,12 +28,7 @@ module Gitlab # connect with Spamcheck @endpoint_url = @endpoint_url.gsub(%r(^grpc:\/\/), '') - @creds = - if Rails.env.development? || Rails.env.test? - :this_channel_is_insecure - else - GRPC::Core::ChannelCredentials.new - end + @creds = stub_creds end def issue_spam?(spam_issue:, user:, context: {}) @@ -98,6 +94,14 @@ module Gitlab nanos: ar_timestamp.to_time.nsec) end + def stub_creds + if Rails.env.development? || Rails.env.test? + :this_channel_is_insecure + else + GRPC::Core::ChannelCredentials.new ::Gitlab::X509::Certificate.ca_certs_bundle + end + end + def grpc_client @grpc_client ||= ::Spamcheck::SpamcheckService::Stub.new(@endpoint_url, @creds, interceptors: interceptors, diff --git a/lib/gitlab/x509/certificate.rb b/lib/gitlab/x509/certificate.rb index c7289a51b49..81a50433be2 100644 --- a/lib/gitlab/x509/certificate.rb +++ b/lib/gitlab/x509/certificate.rb @@ -33,6 +33,26 @@ module Gitlab from_strings(File.read(key_path), File.read(cert_path), ca_certs_string) end + # Returns all top-level, readable files in the default CA cert directory + def self.ca_certs_paths + cert_paths = Dir["#{OpenSSL::X509::DEFAULT_CERT_DIR}/*"].select do |path| + !File.directory?(path) && File.readable?(path) + end + cert_paths << OpenSSL::X509::DEFAULT_CERT_FILE if File.exist? OpenSSL::X509::DEFAULT_CERT_FILE + cert_paths + end + + # Returns a concatenated array of Strings, each being a PEM-coded CA certificate. + def self.ca_certs_bundle + return @certs if @certs + + @certs = ca_certs_paths.flat_map do |cert_file| + load_ca_certs_bundle(File.read(cert_file)) + rescue OpenSSL::OpenSSLError => e + Gitlab::ErrorTracking.track_and_raise_for_dev_exception(e, cert_file: cert_file) + end.uniq.join("\n") + end + # Returns an array of OpenSSL::X509::Certificate objects, empty array if none found # # Ruby OpenSSL::X509::Certificate.new will only load the first diff --git a/lib/sidebars/projects/menus/settings_menu.rb b/lib/sidebars/projects/menus/settings_menu.rb index 6439c97d0bc..2411ca8263a 100644 --- a/lib/sidebars/projects/menus/settings_menu.rb +++ b/lib/sidebars/projects/menus/settings_menu.rb @@ -144,10 +144,6 @@ module Sidebars end def usage_quotas_menu_item - unless Feature.enabled?(:project_storage_ui, context.project&.group, default_enabled: :yaml) - return ::Sidebars::NilMenuItem.new(item_id: :usage_quotas) - end - ::Sidebars::MenuItem.new( title: s_('UsageQuota|Usage Quotas'), link: project_usage_quotas_path(context.project), diff --git a/locale/gitlab.pot b/locale/gitlab.pot index af96e7b092e..8a8fec10953 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -1843,6 +1843,9 @@ msgstr "" msgid "Activate Service Desk" msgstr "" +msgid "Activated on" +msgstr "" + msgid "Active" msgstr "" @@ -13860,6 +13863,9 @@ msgstr "" msgid "Expires in %{expires_at}" msgstr "" +msgid "Expires on" +msgstr "" + msgid "Expires:" msgstr "" @@ -19976,6 +19982,9 @@ msgstr "" msgid "Last Seen" msgstr "" +msgid "Last Sync" +msgstr "" + msgid "Last Used" msgstr "" @@ -25484,6 +25493,9 @@ msgstr "" msgid "Plain-text response to send to clients that hit a rate limit" msgstr "" +msgid "Plan" +msgstr "" + msgid "Plan:" msgstr "" @@ -28593,6 +28605,9 @@ msgstr "" msgid "Renew subscription" msgstr "" +msgid "Renews" +msgstr "" + msgid "Reopen" msgstr "" @@ -30044,6 +30059,9 @@ msgstr[1] "" msgid "Searching by both author and message is currently not supported." msgstr "" +msgid "Seats" +msgstr "" + msgid "Seats usage data as of %{last_enqueue_time} (Updated daily)" msgstr "" @@ -33026,18 +33044,12 @@ msgstr "" msgid "Sunday" msgstr "" -msgid "SuperSonics|Activate" -msgstr "" - msgid "SuperSonics|Activate cloud license" msgstr "" msgid "SuperSonics|Activate subscription" msgstr "" -msgid "SuperSonics|Activated on" -msgstr "" - msgid "SuperSonics|Activation code" msgstr "" @@ -33059,9 +33071,6 @@ msgstr "" msgid "SuperSonics|Cloud licensing is now available. It's an easier way to activate instances and manage subscriptions. Read more about it in our %{blogPostLinkStart}blog post%{blogPostLinkEnd}. Activation codes are available in the %{portalLinkStart}Customers Portal%{portalLinkEnd}." msgstr "" -msgid "SuperSonics|Expires on" -msgstr "" - msgid "SuperSonics|Export license usage file" msgstr "" @@ -33074,12 +33083,6 @@ msgstr "" msgid "SuperSonics|I agree that my use of the GitLab Software is subject to the Subscription Agreement located at the %{linkStart}Terms of Service%{linkEnd}, unless otherwise agreed to in writing with GitLab." msgstr "" -msgid "SuperSonics|ID" -msgstr "" - -msgid "SuperSonics|Last Sync" -msgstr "" - msgid "SuperSonics|Learn how to %{linkStart}activate your subscription%{linkEnd}." msgstr "" @@ -33095,30 +33098,15 @@ msgstr "" msgid "SuperSonics|Paste your activation code" msgstr "" -msgid "SuperSonics|Plan" -msgstr "" - msgid "SuperSonics|Please agree to the Subscription Agreement" msgstr "" msgid "SuperSonics|Ready to get started? A GitLab plan is ideal for scaling organizations and for multi team usage." msgstr "" -msgid "SuperSonics|Renews" -msgstr "" - -msgid "SuperSonics|Seats" -msgstr "" - msgid "SuperSonics|Start free trial" msgstr "" -msgid "SuperSonics|Started" -msgstr "" - -msgid "SuperSonics|Subscription" -msgstr "" - msgid "SuperSonics|Subscription details" msgstr "" @@ -33146,9 +33134,6 @@ msgstr "" msgid "SuperSonics|To activate your subscription, connect to GitLab servers through the %{linkStart}Cloud Licensing%{linkEnd} service, a hassle-free way to manage your subscription." msgstr "" -msgid "SuperSonics|Type" -msgstr "" - msgid "SuperSonics|Upload a license file" msgstr "" @@ -33161,9 +33146,6 @@ msgstr "" msgid "SuperSonics|Users with a Guest role or those who don't belong to a Project or Group will not use a seat from your license." msgstr "" -msgid "SuperSonics|Valid From" -msgstr "" - msgid "SuperSonics|You can learn more about %{activationLinkStart}activating your subscription%{activationLinkEnd}. If you need further assistance, please %{supportLinkStart}contact GitLab Support%{supportLinkEnd}." msgstr "" @@ -37487,6 +37469,9 @@ msgstr "" msgid "Using the %{codeStart}needs%{codeEnd} keyword makes jobs run before their stage is reached. Jobs run as soon as their %{codeStart}needs%{codeEnd} relationships are met, which speeds up your pipelines." msgstr "" +msgid "Valid From" +msgstr "" + msgid "Validate" msgstr "" @@ -39681,6 +39666,9 @@ msgstr "" msgid "Zentao issues" msgstr "" +msgid "Zentao user" +msgstr "" + msgid "ZentaoIntegration|An error occurred while requesting data from the ZenTao service." msgstr "" diff --git a/spec/features/projects/environments/environment_spec.rb b/spec/features/projects/environments/environment_spec.rb index 5320f68b525..bcbf2f46f79 100644 --- a/spec/features/projects/environments/environment_spec.rb +++ b/spec/features/projects/environments/environment_spec.rb @@ -23,10 +23,6 @@ RSpec.describe 'Environment' do let!(:action) { } let!(:cluster) { } - before do - visit_environment(environment) - end - context 'with auto-stop' do let!(:environment) { create(:environment, :will_auto_stop, name: 'staging', project: project) } @@ -52,12 +48,20 @@ RSpec.describe 'Environment' do end context 'without deployments' do + before do + visit_environment(environment) + end + it 'does not show deployments' do expect(page).to have_content('You don\'t have any deployments right now.') end end context 'with deployments' do + before do + visit_environment(environment) + end + context 'when there is no related deployable' do let(:deployment) do create(:deployment, :success, environment: environment, deployable: nil) @@ -108,6 +112,26 @@ RSpec.describe 'Environment' do end end + context 'with many deployments' do + let(:pipeline) { create(:ci_pipeline, project: project) } + let(:build) { create(:ci_build, pipeline: pipeline) } + + let!(:second) { create(:deployment, environment: environment, deployable: build, status: :success, finished_at: Time.current) } + let!(:first) { create(:deployment, environment: environment, deployable: build, status: :running) } + let!(:last) { create(:deployment, environment: environment, deployable: build, status: :success, finished_at: 2.days.ago) } + let!(:third) { create(:deployment, environment: environment, deployable: build, status: :canceled, finished_at: 1.day.ago) } + + before do + visit_environment(environment) + end + + it 'shows all of them in ordered way' do + ids = find_all('[data-testid="deployment-id"]').map { |e| e.text } + expected_ordered_ids = [first, second, third, last].map { |d| "##{d.iid}" } + expect(ids).to eq(expected_ordered_ids) + end + end + context 'with related deployable present' do let(:pipeline) { create(:ci_pipeline, project: project) } let(:build) { create(:ci_build, pipeline: pipeline) } @@ -116,6 +140,10 @@ RSpec.describe 'Environment' do create(:deployment, :success, environment: environment, deployable: build) end + before do + visit_environment(environment) + end + it 'does show build name' do expect(page).to have_link("#{build.name} (##{build.id})") end diff --git a/spec/lib/gitlab/gitaly_client_spec.rb b/spec/lib/gitlab/gitaly_client_spec.rb index 16f75691288..ba4ea1069d8 100644 --- a/spec/lib/gitlab/gitaly_client_spec.rb +++ b/spec/lib/gitlab/gitaly_client_spec.rb @@ -5,14 +5,6 @@ require 'spec_helper' # We stub Gitaly in `spec/support/gitaly.rb` for other tests. We don't want # those stubs while testing the GitalyClient itself. RSpec.describe Gitlab::GitalyClient do - let(:sample_cert) { Rails.root.join('spec/fixtures/clusters/sample_cert.pem').to_s } - - before do - allow(described_class) - .to receive(:stub_cert_paths) - .and_return([sample_cert]) - end - def stub_repos_storages(address) allow(Gitlab.config.repositories).to receive(:storages).and_return({ 'default' => { 'gitaly_address' => address } @@ -142,21 +134,6 @@ RSpec.describe Gitlab::GitalyClient do end end - describe '.stub_certs' do - it 'skips certificates if OpenSSLError is raised and report it' do - expect(Gitlab::ErrorTracking) - .to receive(:track_and_raise_for_dev_exception) - .with( - a_kind_of(OpenSSL::X509::CertificateError), - cert_file: a_kind_of(String)).at_least(:once) - - expect(OpenSSL::X509::Certificate) - .to receive(:new) - .and_raise(OpenSSL::X509::CertificateError).at_least(:once) - - expect(described_class.stub_certs).to be_a(String) - end - end describe '.stub_creds' do it 'returns :this_channel_is_insecure if unix' do address = 'unix:/tmp/gitaly.sock' diff --git a/spec/lib/gitlab/x509/certificate_spec.rb b/spec/lib/gitlab/x509/certificate_spec.rb index a5b192dd051..4e1a269eecf 100644 --- a/spec/lib/gitlab/x509/certificate_spec.rb +++ b/spec/lib/gitlab/x509/certificate_spec.rb @@ -5,6 +5,9 @@ require 'spec_helper' RSpec.describe Gitlab::X509::Certificate do include SmimeHelper + let(:sample_ca_certs_path) { Rails.root.join('spec/fixtures/clusters').to_s } + let(:sample_cert) { Rails.root.join('spec/fixtures/x509_certificate.crt').to_s } + # cert generation is an expensive operation and they are used read-only, # so we share them as instance variables in all tests before :context do @@ -13,6 +16,11 @@ RSpec.describe Gitlab::X509::Certificate do @cert = generate_cert(signer_ca: @intermediate_ca) end + before do + stub_const("OpenSSL::X509::DEFAULT_CERT_DIR", sample_ca_certs_path) + stub_const("OpenSSL::X509::DEFAULT_CERT_FILE", sample_cert) + end + describe 'testing environment setup' do describe 'generate_root' do subject { @root_ca } @@ -103,6 +111,43 @@ RSpec.describe Gitlab::X509::Certificate do end end + describe '.ca_certs_paths' do + it 'returns all files specified by OpenSSL defaults' do + cert_paths = Dir["#{OpenSSL::X509::DEFAULT_CERT_DIR}/*"] + + expect(described_class.ca_certs_paths).to match_array(cert_paths + [sample_cert]) + end + end + + describe '.ca_certs_bundle' do + it 'skips certificates if OpenSSLError is raised and report it' do + expect(Gitlab::ErrorTracking) + .to receive(:track_and_raise_for_dev_exception) + .with( + a_kind_of(OpenSSL::X509::CertificateError), + cert_file: a_kind_of(String)).at_least(:once) + + expect(OpenSSL::X509::Certificate) + .to receive(:new) + .and_raise(OpenSSL::X509::CertificateError).at_least(:once) + + expect(described_class.ca_certs_bundle).to be_a(String) + end + + it 'returns a list certificates as strings' do + expect(described_class.ca_certs_bundle).to be_a(String) + end + end + + describe '.load_ca_certs_bundle' do + it 'loads a PEM-encoded certificate bundle into an OpenSSL::X509::Certificate array' do + ca_certs_string = described_class.ca_certs_bundle + ca_certs = described_class.load_ca_certs_bundle(ca_certs_string) + + expect(ca_certs).to all(be_an(OpenSSL::X509::Certificate)) + end + end + def common_cert_tests(parsed_cert, cert, signer_ca, with_ca_certs: nil) expect(parsed_cert.cert).to be_a(OpenSSL::X509::Certificate) expect(parsed_cert.cert.subject).to eq(cert[:cert].subject) diff --git a/spec/lib/sidebars/projects/menus/settings_menu_spec.rb b/spec/lib/sidebars/projects/menus/settings_menu_spec.rb index 3079c781d73..1e5d41dfec4 100644 --- a/spec/lib/sidebars/projects/menus/settings_menu_spec.rb +++ b/spec/lib/sidebars/projects/menus/settings_menu_spec.rb @@ -162,24 +162,10 @@ RSpec.describe Sidebars::Projects::Menus::SettingsMenu do describe 'Usage Quotas' do let(:item_id) { :usage_quotas } - describe 'with project_storage_ui feature flag enabled' do - before do - stub_feature_flags(project_storage_ui: true) - end + specify { is_expected.not_to be_nil } - specify { is_expected.not_to be_nil } - - describe 'when the user does not have access' do - let(:user) { nil } - - specify { is_expected.to be_nil } - end - end - - describe 'with project_storage_ui feature flag disabled' do - before do - stub_feature_flags(project_storage_ui: false) - end + describe 'when the user does not have access' do + let(:user) { nil } specify { is_expected.to be_nil } end diff --git a/spec/models/deployment_spec.rb b/spec/models/deployment_spec.rb index f9a05fbb06f..d3161db3f02 100644 --- a/spec/models/deployment_spec.rb +++ b/spec/models/deployment_spec.rb @@ -456,6 +456,17 @@ RSpec.describe Deployment do end end + describe '.ordered' do + let!(:deployment1) { create(:deployment, status: :running) } + let!(:deployment2) { create(:deployment, status: :success, finished_at: Time.current) } + let!(:deployment3) { create(:deployment, status: :canceled, finished_at: 1.day.ago) } + let!(:deployment4) { create(:deployment, status: :success, finished_at: 2.days.ago) } + + it 'sorts by finished at' do + expect(described_class.ordered).to eq([deployment1, deployment2, deployment3, deployment4]) + end + end + describe 'visible' do subject { described_class.visible } diff --git a/spec/requests/projects/usage_quotas_spec.rb b/spec/requests/projects/usage_quotas_spec.rb index 04e01da61ef..114e9bd9f1e 100644 --- a/spec/requests/projects/usage_quotas_spec.rb +++ b/spec/requests/projects/usage_quotas_spec.rb @@ -22,40 +22,26 @@ RSpec.describe 'Project Usage Quotas' do end describe 'GET /:namespace/:project/usage_quotas' do - context 'with project_storage_ui feature flag enabled' do - before do - stub_feature_flags(project_storage_ui: true) - end + it 'renders usage quotas path' do + mock_storage_app_data = { + project_path: project.full_path, + usage_quotas_help_page_path: help_page_path('user/usage_quotas'), + build_artifacts_help_page_path: help_page_path('ci/pipelines/job_artifacts', anchor: 'when-job-artifacts-are-deleted'), + packages_help_page_path: help_page_path('user/packages/package_registry/index.md', anchor: 'delete-a-package'), + repository_help_page_path: help_page_path('user/project/repository/reducing_the_repo_size_using_git'), + snippets_help_page_path: help_page_path('user/snippets', anchor: 'reduce-snippets-repository-size'), + wiki_help_page_path: help_page_path('administration/wikis/index.md', anchor: 'reduce-wiki-repository-size') + } + get project_usage_quotas_path(project) - it 'renders usage quotas path' do - mock_storage_app_data = { - project_path: project.full_path, - usage_quotas_help_page_path: help_page_path('user/usage_quotas'), - build_artifacts_help_page_path: help_page_path('ci/pipelines/job_artifacts', anchor: 'when-job-artifacts-are-deleted'), - packages_help_page_path: help_page_path('user/packages/package_registry/index.md', anchor: 'delete-a-package'), - repository_help_page_path: help_page_path('user/project/repository/reducing_the_repo_size_using_git'), - snippets_help_page_path: help_page_path('user/snippets', anchor: 'reduce-snippets-repository-size'), - wiki_help_page_path: help_page_path('administration/wikis/index.md', anchor: 'reduce-wiki-repository-size') - } - get project_usage_quotas_path(project) - - expect(response).to have_gitlab_http_status(:ok) - expect(response.body).to include(project_usage_quotas_path(project)) - expect(assigns[:storage_app_data]).to eq(mock_storage_app_data) - expect(response.body).to include("Usage of project resources across the #{project.name} project") - end - - context 'renders :not_found for user without permission' do - let(:role) { :developer } - - it_behaves_like 'response with 404 status' - end + expect(response).to have_gitlab_http_status(:ok) + expect(response.body).to include(project_usage_quotas_path(project)) + expect(assigns[:storage_app_data]).to eq(mock_storage_app_data) + expect(response.body).to include("Usage of project resources across the #{project.name} project") end - context 'with project_storage_ui feature flag disabled' do - before do - stub_feature_flags(project_storage_ui: false) - end + context 'renders :not_found for user without permission' do + let(:role) { :developer } it_behaves_like 'response with 404 status' end diff --git a/spec/support/database/cross-join-allowlist.yml b/spec/support/database/cross-join-allowlist.yml index 54375e43833..86b2ba9333c 100644 --- a/spec/support/database/cross-join-allowlist.yml +++ b/spec/support/database/cross-join-allowlist.yml @@ -1,4 +1,3 @@ -- "./ee/spec/features/ci/ci_minutes_spec.rb" - "./ee/spec/features/merge_trains/two_merge_requests_on_train_spec.rb" - "./ee/spec/features/merge_trains/user_adds_merge_request_to_merge_train_spec.rb" - "./ee/spec/finders/ee/namespaces/projects_finder_spec.rb" diff --git a/spec/support/shared_contexts/navbar_structure_context.rb b/spec/support/shared_contexts/navbar_structure_context.rb index 2abc52fce85..bcc6abdc308 100644 --- a/spec/support/shared_contexts/navbar_structure_context.rb +++ b/spec/support/shared_contexts/navbar_structure_context.rb @@ -119,7 +119,7 @@ RSpec.shared_context 'project navbar structure' do _('Repository'), _('CI/CD'), _('Monitor'), - (s_('UsageQuota|Usage Quotas') if Feature.enabled?(:project_storage_ui, default_enabled: :yaml)) + s_('UsageQuota|Usage Quotas') ] } ].compact diff --git a/spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb b/spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb index 20c5d9992be..f7da288b9f3 100644 --- a/spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb +++ b/spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb @@ -987,28 +987,10 @@ RSpec.describe 'layouts/nav/sidebar/_project' do end describe 'Usage Quotas' do - context 'with project_storage_ui feature flag enabled' do - before do - stub_feature_flags(project_storage_ui: true) - end + it 'has a link to Usage Quotas' do + render - it 'has a link to Usage Quotas' do - render - - expect(rendered).to have_link('Usage Quotas', href: project_usage_quotas_path(project)) - end - end - - context 'with project_storage_ui feature flag disabled' do - before do - stub_feature_flags(project_storage_ui: false) - end - - it 'does not have a link to Usage Quotas' do - render - - expect(rendered).not_to have_link('Usage Quotas', href: project_usage_quotas_path(project)) - end + expect(rendered).to have_link('Usage Quotas', href: project_usage_quotas_path(project)) end end end