Skip to content
Snippets Groups Projects
Commit 5396a6b6 authored by Bob Van Landuyt's avatar Bob Van Landuyt
Browse files

Merge branch 'fill-in-namespace-storage-enforcement-service' into 'master'

Add Additional Checks to Namespace Enforcement Check Service

See merge request !91097
parents f73d8b92 01cd4e06
No related branches found
No related tags found
1 merge request!91097Add Additional Checks to Namespace Enforcement Check Service
Pipeline #581740766 failed
Pipeline: GitLab

#581744365

    ......@@ -5,8 +5,6 @@ class Namespace::RootStorageSize
    CURRENT_SIZE_CACHE_KEY = 'root_storage_current_size'
    LIMIT_CACHE_KEY = 'root_storage_size_limit'
    EXPIRATION_TIME = 10.minutes
    EFFECTIVE_DATE = 99.years.from_now.to_date
    ENFORCEMENT_DATE = 100.years.from_now.to_date
    def initialize(root_namespace)
    @root_namespace = root_namespace
    ......@@ -47,12 +45,10 @@ def remaining_storage_size
    end
    def enforce_limit?
    return false unless enforceable_dates?
    return false if root_namespace.opensource_plan?
    return ::Feature.enabled?(:enforce_storage_limit_for_paid, root_namespace) if root_namespace.paid?
    ::Feature.enabled?(:enforce_storage_limit_for_free, root_namespace)
    # Refactor in https://gitlab.com/gitlab-org/gitlab/-/issues/366938
    # rubocop:disable CodeReuse/ServiceClass
    ::Namespaces::Storage::EnforcementCheckService.enforce_limit?(root_namespace)
    # rubocop:enable CodeReuse/ServiceClass
    end
    alias_method :enabled?, :enforce_limit?
    ......@@ -73,11 +69,6 @@ def changes_will_exceed_size_limit?(change_size)
    private
    def enforceable_dates?
    ::Feature.enabled?(:namespace_storage_limit_bypass_date_check, root_namespace) ||
    (Date.current >= ENFORCEMENT_DATE && gitlab_subscription.start_date >= EFFECTIVE_DATE)
    end
    attr_reader :root_namespace
    delegate :gitlab_subscription, to: :root_namespace
    ......
    ......@@ -3,9 +3,32 @@
    module Namespaces
    module Storage
    class EnforcementCheckService
    ENFORCEMENT_DATE = 100.years.from_now.to_date
    EFFECTIVE_DATE = 99.years.from_now.to_date
    def self.enforce_limit?(namespace)
    root_namespace = namespace.root_ancestor
    ::Gitlab::CurrentSettings.enforce_namespace_storage_limit? &&
    ::Feature.enabled?(:namespace_storage_limit, namespace)
    ::Gitlab::CurrentSettings.automatic_purchased_storage_allocation? &&
    ::Feature.enabled?(:namespace_storage_limit, root_namespace) &&
    enforceable_plan?(root_namespace) &&
    enforceable_dates?(root_namespace)
    end
    private_class_method def self.enforceable_plan?(root_namespace)
    return false if root_namespace.opensource_plan?
    if root_namespace.paid?
    ::Feature.enabled?(:enforce_storage_limit_for_paid, root_namespace)
    else
    ::Feature.enabled?(:enforce_storage_limit_for_free, root_namespace)
    end
    end
    private_class_method def self.enforceable_dates?(root_namespace)
    ::Feature.enabled?(:namespace_storage_limit_bypass_date_check, root_namespace) ||
    (Date.current >= ENFORCEMENT_DATE && root_namespace.gitlab_subscription.start_date >= EFFECTIVE_DATE)
    end
    end
    end
    ......
    ......@@ -31,6 +31,8 @@
    with_them do
    before do
    stub_ee_application_setting(should_check_namespace_plan: true)
    stub_ee_application_setting(enforce_namespace_storage_limit: true)
    stub_ee_application_setting(automatic_purchased_storage_allocation: true)
    allow(namespace).to receive(:additional_repo_storage_by_namespace_enabled?)
    .and_return(additional_repo_storage_by_namespace_enabled)
    ......
    ......@@ -209,6 +209,10 @@
    describe '#enforce_limit?' do
    before do
    stub_feature_flags(namespace_storage_limit_bypass_date_check: false)
    stub_application_setting(
    enforce_namespace_storage_limit: true,
    automatic_purchased_storage_allocation: true
    )
    end
    around do |example|
    ......@@ -226,7 +230,7 @@
    end
    context 'when current date is before enforcement date' do
    let(:current_date) { described_class::ENFORCEMENT_DATE - 1.day }
    let(:current_date) { ::Namespaces::Storage::EnforcementCheckService::ENFORCEMENT_DATE - 1.day }
    it { is_expected.to eq(false) }
    ......@@ -234,12 +238,11 @@
    end
    context 'when current date is on or after enforcement date' do
    let(:current_date) { described_class::ENFORCEMENT_DATE }
    let(:current_date) { ::Namespaces::Storage::EnforcementCheckService::ENFORCEMENT_DATE }
    context 'when no subscription is found for namespace' do
    before do
    subscription.destroy!
    end
    let(:namespace_without_subscription) { create(:namespace) }
    let(:model) { described_class.new(namespace_without_subscription) }
    it { is_expected.to eq(true) }
    end
    ......@@ -253,7 +256,7 @@
    end
    context 'when subscription start date is before effective date' do
    let(:start_date) { described_class::EFFECTIVE_DATE - 1.day }
    let(:start_date) { ::Namespaces::Storage::EnforcementCheckService::EFFECTIVE_DATE - 1.day }
    before do
    allow(subscription).to receive(:start_date).and_return(start_date)
    ......
    ......@@ -13,6 +13,8 @@
    before do
    group.add_owner(user)
    stub_ee_application_setting(should_check_namespace_plan: true)
    stub_ee_application_setting(enforce_namespace_storage_limit: true)
    stub_ee_application_setting(automatic_purchased_storage_allocation: true)
    allow_next_instance_of(EE::Namespace::Storage::Notification) do |notification|
    allow(notification).to receive(:alert_level).and_return(alert_level)
    end
    ......
    ......@@ -114,6 +114,8 @@
    with_them do
    before do
    stub_ee_application_setting(should_check_namespace_plan: true)
    stub_ee_application_setting(enforce_namespace_storage_limit: true)
    stub_ee_application_setting(automatic_purchased_storage_allocation: true)
    allow(project.namespace).to receive(:additional_repo_storage_by_namespace_enabled?)
    .and_return(additional_repo_storage_by_namespace_enabled)
    ......
    ......@@ -2,29 +2,232 @@
    require 'spec_helper'
    RSpec.describe ::Namespaces::Storage::EnforcementCheckService do
    let_it_be(:group) { create(:group) }
    RSpec.describe ::Namespaces::Storage::EnforcementCheckService, :saas do
    describe '.enforce_limit?' do
    before do
    stub_feature_flags(namespace_storage_limit: group)
    stub_application_setting(enforce_namespace_storage_limit: true)
    stub_feature_flags(
    namespace_storage_limit: group,
    enforce_storage_limit_for_free: group,
    enforce_storage_limit_for_paid: group,
    namespace_storage_limit_bypass_date_check: false
    )
    stub_application_setting(
    enforce_namespace_storage_limit: true,
    automatic_purchased_storage_allocation: true
    )
    stub_enforcement_date(Date.today)
    stub_effective_date(group.gitlab_subscription&.start_date || 1.year.ago.to_date)
    end
    context 'with a free plan' do
    let_it_be(:group) { create(:group_with_plan, plan: :free_plan) }
    it 'returns true when namespace storage limits are enforced for the namespace' do
    expect(described_class.enforce_limit?(group)).to eq(true)
    end
    it 'returns true when the enforce_storage_limit_for_paid feature flag is disabled' do
    stub_feature_flags(enforce_storage_limit_for_paid: false)
    expect(described_class.enforce_limit?(group)).to eq(true)
    end
    it 'returns true when the namespace_storage_limit_bypass_date_check flag is enabled regardless of dates' do
    stub_enforcement_date(Date.tomorrow)
    stub_effective_date(group.gitlab_subscription.start_date + 1.day)
    stub_feature_flags(namespace_storage_limit_bypass_date_check: group)
    expect(described_class.enforce_limit?(group)).to eq(true)
    end
    it 'returns false when the namespace_storage_limit feature flag is disabled' do
    stub_feature_flags(namespace_storage_limit: false)
    expect(described_class.enforce_limit?(group)).to eq(false)
    end
    it 'returns false when the enforce_storage_limit_for_free feature flag is disabled' do
    stub_feature_flags(enforce_storage_limit_for_free: false)
    expect(described_class.enforce_limit?(group)).to eq(false)
    end
    it 'returns false when the enforce_namespace_storage_limit application setting is disabled' do
    stub_application_setting(enforce_namespace_storage_limit: false)
    expect(described_class.enforce_limit?(group)).to eq(false)
    end
    it 'returns false when the automatic_purchased_storage_allocation application setting is disabled' do
    stub_application_setting(automatic_purchased_storage_allocation: false)
    expect(described_class.enforce_limit?(group)).to eq(false)
    end
    it 'returns false if the enforcement date is in the future' do
    stub_enforcement_date(Date.tomorrow)
    expect(described_class.enforce_limit?(group)).to eq(false)
    end
    it 'returns false if the effective date is after the subscription start date' do
    stub_effective_date(group.gitlab_subscription.start_date + 1.day)
    expect(described_class.enforce_limit?(group)).to eq(false)
    end
    end
    context 'with a paid plan' do
    let_it_be(:group) { create(:group_with_plan, plan: :ultimate_plan) }
    it 'returns true when namespace storage limits are enforced for the namespace' do
    expect(described_class.enforce_limit?(group)).to eq(true)
    end
    it 'returns true when the enforce_storage_limit_for_free feature flag is disabled' do
    stub_feature_flags(enforce_storage_limit_for_free: false)
    expect(described_class.enforce_limit?(group)).to eq(true)
    end
    it 'returns true when the namespace_storage_limit_bypass_date_check flag is enabled regardless of dates' do
    stub_enforcement_date(Date.tomorrow)
    stub_effective_date(group.gitlab_subscription.start_date + 1.day)
    stub_feature_flags(namespace_storage_limit_bypass_date_check: group)
    expect(described_class.enforce_limit?(group)).to eq(true)
    end
    it 'returns false when the enforce_storage_limit_for_paid feature flag is disabled' do
    stub_feature_flags(enforce_storage_limit_for_paid: false)
    expect(described_class.enforce_limit?(group)).to eq(false)
    end
    it 'returns false when the namespace_storage_limit feature flag is disabled' do
    stub_feature_flags(namespace_storage_limit: false)
    expect(described_class.enforce_limit?(group)).to eq(false)
    end
    it 'returns false when the enforce_namespace_storage_limit application setting is disabled' do
    stub_application_setting(enforce_namespace_storage_limit: false)
    expect(described_class.enforce_limit?(group)).to eq(false)
    end
    it 'returns false when the automatic_purchased_storage_allocation application setting is disabled' do
    stub_application_setting(automatic_purchased_storage_allocation: false)
    expect(described_class.enforce_limit?(group)).to eq(false)
    end
    it 'returns false if the enforcement date is in the future' do
    stub_enforcement_date(Date.tomorrow)
    expect(described_class.enforce_limit?(group)).to eq(false)
    end
    it 'returns false if the effective date is after the subscription start date' do
    stub_effective_date(group.gitlab_subscription.start_date + 1.day)
    expect(described_class.enforce_limit?(group)).to eq(false)
    end
    end
    it 'returns true when namespace storage limits are enforced for the namespace' do
    expect(described_class.enforce_limit?(group)).to eq(true)
    context 'with an open source plan' do
    let_it_be(:group) { create(:group_with_plan, plan: :opensource_plan) }
    it 'returns false even when namespace storage limits are enforced' do
    expect(described_class.enforce_limit?(group)).to eq(false)
    end
    end
    it 'returns false when the feature flag is disabled' do
    stub_feature_flags(namespace_storage_limit: false)
    context 'without a plan' do
    let(:group) { create(:group) }
    it 'returns true when namespace storage limits are enforced for the namespace' do
    expect(described_class.enforce_limit?(group)).to eq(true)
    end
    it 'returns true when the enforce_storage_limit_for_paid feature flag is disabled' do
    stub_feature_flags(enforce_storage_limit_for_paid: false)
    expect(described_class.enforce_limit?(group)).to eq(true)
    end
    it 'returns true when the namespace_storage_limit_bypass_date_check flag is enabled regardless of dates' do
    stub_enforcement_date(Date.tomorrow)
    stub_effective_date(Date.tomorrow)
    stub_feature_flags(namespace_storage_limit_bypass_date_check: group)
    expect(described_class.enforce_limit?(group)).to eq(true)
    end
    it 'returns false when the namespace_storage_limit feature flag is disabled' do
    stub_feature_flags(namespace_storage_limit: false)
    expect(described_class.enforce_limit?(group)).to eq(false)
    end
    it 'returns false when the enforce_storage_limit_for_free feature flag is disabled' do
    stub_feature_flags(enforce_storage_limit_for_free: false)
    expect(described_class.enforce_limit?(group)).to eq(false)
    end
    it 'returns false when the enforce_namespace_storage_limit application setting is disabled' do
    stub_application_setting(enforce_namespace_storage_limit: false)
    expect(described_class.enforce_limit?(group)).to eq(false)
    expect(described_class.enforce_limit?(group)).to eq(false)
    end
    it 'returns false when the automatic_purchased_storage_allocation application setting is disabled' do
    stub_application_setting(automatic_purchased_storage_allocation: false)
    expect(described_class.enforce_limit?(group)).to eq(false)
    end
    it 'returns false if the enforcement date is in the future' do
    stub_enforcement_date(Date.tomorrow)
    expect(described_class.enforce_limit?(group)).to eq(false)
    end
    it 'returns false if the effective date is in the future' do
    stub_effective_date(Date.tomorrow)
    expect(described_class.enforce_limit?(group)).to eq(false)
    end
    end
    context 'with a subgroup' do
    let_it_be(:group) { create(:group_with_plan, plan: :free_plan) }
    let_it_be(:subgroup) { create(:group, parent: group) }
    it 'returns true when namespace storage limits are enforced for the root namespace' do
    expect(described_class.enforce_limit?(subgroup)).to eq(true)
    end
    end
    end
    it 'returns false when the application setting is disabled' do
    stub_application_setting(enforce_namespace_storage_limit: false)
    describe 'ENFORCEMENT_DATE' do
    it 'is 100 years from today' do
    expect(described_class::ENFORCEMENT_DATE).to eq(100.years.from_now.to_date)
    end
    end
    expect(described_class.enforce_limit?(group)).to eq(false)
    describe 'EFFECTIVE_DATE' do
    it 'is 99 years from today' do
    expect(described_class::EFFECTIVE_DATE).to eq(99.years.from_now.to_date)
    end
    end
    def stub_enforcement_date(date)
    stub_const('::Namespaces::Storage::EnforcementCheckService::ENFORCEMENT_DATE', date)
    end
    def stub_effective_date(date)
    stub_const('::Namespaces::Storage::EnforcementCheckService::EFFECTIVE_DATE', date)
    end
    end
    ......@@ -12,8 +12,8 @@ def set_used_storage(namespace, megabytes:)
    def enforce_namespace_storage_limit(root_namespace)
    stub_application_setting(enforce_namespace_storage_limit: true)
    stub_application_setting(automatic_purchased_storage_allocation: true)
    stub_const('EE::Namespace::RootStorageSize::EFFECTIVE_DATE', 2.years.ago.to_date)
    stub_const('EE::Namespace::RootStorageSize::ENFORCEMENT_DATE', 1.year.ago.to_date)
    stub_const('::Namespaces::Storage::EnforcementCheckService::EFFECTIVE_DATE', 2.years.ago.to_date)
    stub_const('::Namespaces::Storage::EnforcementCheckService::ENFORCEMENT_DATE', 1.year.ago.to_date)
    stub_feature_flags(
    namespace_storage_limit: root_namespace,
    enforce_storage_limit_for_paid: root_namespace,
    ......
    ......@@ -5,6 +5,8 @@
    before do
    stub_ee_application_setting(should_check_namespace_plan: true)
    stub_ee_application_setting(enforce_namespace_storage_limit: true)
    stub_ee_application_setting(automatic_purchased_storage_allocation: true)
    allow_next_instance_of(EE::Namespace::Storage::Notification, namespace, user) do |notification|
    allow(notification).to receive(:payload).and_return({
    alert_level: alert_level,
    ......
    0% Loading or .
    You are about to add 0 people to the discussion. Proceed with caution.
    Finish editing this message first!
    Please register or to comment