Commit 82bcdd66 authored by Nicolas Dular's avatar Nicolas Dular

Check for temporary storage size being enabled

This adds a check for the temporary storage size end date and
exposes it to the GraphQL API.

If the date is set and in the future or the current date the
namespace will not be checked if it exceeds the limit.

To make it easier for the UI to determine if the temporary
storage is currently active or not, we expose this field in our
GraphQL API. This way the UI does not need to check and compare
the date on its own.
parent 9db5eb50
...@@ -5049,6 +5049,11 @@ type Group { ...@@ -5049,6 +5049,11 @@ type Group {
""" """
id: ID! id: ID!
"""
Status of the temporary storage increase
"""
isTemporaryStorageIncreaseEnabled: Boolean!
""" """
Issues of the group Issues of the group
""" """
...@@ -8306,6 +8311,11 @@ type Namespace { ...@@ -8306,6 +8311,11 @@ type Namespace {
""" """
id: ID! id: ID!
"""
Status of the temporary storage increase
"""
isTemporaryStorageIncreaseEnabled: Boolean!
""" """
Indicates if Large File Storage (LFS) is enabled for namespace Indicates if Large File Storage (LFS) is enabled for namespace
""" """
......
...@@ -14061,6 +14061,24 @@ ...@@ -14061,6 +14061,24 @@
"isDeprecated": false, "isDeprecated": false,
"deprecationReason": null "deprecationReason": null
}, },
{
"name": "isTemporaryStorageIncreaseEnabled",
"description": "Status of the temporary storage increase",
"args": [
],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "Boolean",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{ {
"name": "issues", "name": "issues",
"description": "Issues of the group", "description": "Issues of the group",
...@@ -24788,6 +24806,24 @@ ...@@ -24788,6 +24806,24 @@
"isDeprecated": false, "isDeprecated": false,
"deprecationReason": null "deprecationReason": null
}, },
{
"name": "isTemporaryStorageIncreaseEnabled",
"description": "Status of the temporary storage increase",
"args": [
],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "Boolean",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{ {
"name": "lfsEnabled", "name": "lfsEnabled",
"description": "Indicates if Large File Storage (LFS) is enabled for namespace", "description": "Indicates if Large File Storage (LFS) is enabled for namespace",
...@@ -820,6 +820,7 @@ Autogenerated return type of EpicTreeReorder ...@@ -820,6 +820,7 @@ Autogenerated return type of EpicTreeReorder
| `fullPath` | ID! | Full path of the namespace | | `fullPath` | ID! | Full path of the namespace |
| `groupTimelogsEnabled` | Boolean | Indicates if Group timelogs are enabled for namespace | | `groupTimelogsEnabled` | Boolean | Indicates if Group timelogs are enabled for namespace |
| `id` | ID! | ID of the namespace | | `id` | ID! | ID of the namespace |
| `isTemporaryStorageIncreaseEnabled` | Boolean! | Status of the temporary storage increase |
| `label` | Label | A label available on this group | | `label` | Label | A label available on this group |
| `lfsEnabled` | Boolean | Indicates if Large File Storage (LFS) is enabled for namespace | | `lfsEnabled` | Boolean | Indicates if Large File Storage (LFS) is enabled for namespace |
| `mentionsDisabled` | Boolean | Indicates if a group is disabled from getting mentioned | | `mentionsDisabled` | Boolean | Indicates if a group is disabled from getting mentioned |
...@@ -1276,6 +1277,7 @@ Contains statistics about a milestone ...@@ -1276,6 +1277,7 @@ Contains statistics about a milestone
| `fullName` | String! | Full name of the namespace | | `fullName` | String! | Full name of the namespace |
| `fullPath` | ID! | Full path of the namespace | | `fullPath` | ID! | Full path of the namespace |
| `id` | ID! | ID of the namespace | | `id` | ID! | ID of the namespace |
| `isTemporaryStorageIncreaseEnabled` | Boolean! | Status of the temporary storage increase |
| `lfsEnabled` | Boolean | Indicates if Large File Storage (LFS) is enabled for namespace | | `lfsEnabled` | Boolean | Indicates if Large File Storage (LFS) is enabled for namespace |
| `name` | String! | Name of the namespace | | `name` | String! | Name of the namespace |
| `path` | String! | Path of the namespace | | `path` | String! | Path of the namespace |
......
...@@ -12,6 +12,12 @@ module EE ...@@ -12,6 +12,12 @@ module EE
description: 'Total storage limit of the root namespace in bytes', description: 'Total storage limit of the root namespace in bytes',
resolve: -> (obj, _args, _ctx) { EE::Namespace::RootStorageSize.new(obj).limit } resolve: -> (obj, _args, _ctx) { EE::Namespace::RootStorageSize.new(obj).limit }
field :is_temporary_storage_increase_enabled,
GraphQL::BOOLEAN_TYPE,
null: false,
description: 'Status of the temporary storage increase',
resolve: -> (obj, _args, _ctx) { obj.temporary_storage_increase_enabled? }
field :temporary_storage_increase_ends_on, field :temporary_storage_increase_ends_on,
::Types::TimeType, ::Types::TimeType,
null: true, null: true,
......
...@@ -50,8 +50,8 @@ module EE ...@@ -50,8 +50,8 @@ module EE
delegate :additional_purchased_storage_size, :additional_purchased_storage_size=, delegate :additional_purchased_storage_size, :additional_purchased_storage_size=,
:additional_purchased_storage_ends_on, :additional_purchased_storage_ends_on=, :additional_purchased_storage_ends_on, :additional_purchased_storage_ends_on=,
:temporary_storage_increase_ends_on, :temporary_storage_increase_ends_on, :temporary_storage_increase_ends_on=,
to: :namespace_limit, allow_nil: true :temporary_storage_increase_enabled?, to: :namespace_limit, allow_nil: true
delegate :email, to: :owner, allow_nil: true, prefix: true delegate :email, to: :owner, allow_nil: true, prefix: true
......
...@@ -11,6 +11,8 @@ module EE ...@@ -11,6 +11,8 @@ module EE
end end
def above_size_limit? def above_size_limit?
return false if root_namespace.temporary_storage_increase_enabled?
usage_ratio > 1 usage_ratio > 1
end end
......
...@@ -4,4 +4,11 @@ class NamespaceLimit < ApplicationRecord ...@@ -4,4 +4,11 @@ class NamespaceLimit < ApplicationRecord
self.primary_key = :namespace_id self.primary_key = :namespace_id
belongs_to :namespace, inverse_of: :namespace_limit belongs_to :namespace, inverse_of: :namespace_limit
def temporary_storage_increase_enabled?
return false unless ::Feature.enabled?(:temporary_storage_increase, namespace)
return false if temporary_storage_increase_ends_on.nil?
temporary_storage_increase_ends_on >= Date.today
end
end end
---
title: Expose status of temporary storage increase
merge_request: 37511
author:
type: added
# frozen_string_literal: true
FactoryBot.define do
factory :namespace_limit do
namespace
end
end
...@@ -4,7 +4,7 @@ require 'spec_helper' ...@@ -4,7 +4,7 @@ require 'spec_helper'
RSpec.describe GitlabSchema.types['Namespace'] do RSpec.describe GitlabSchema.types['Namespace'] do
it 'has specific fields' do it 'has specific fields' do
expected_fields = %w[storage_size_limit temporary_storage_increase_ends_on] expected_fields = %w[storage_size_limit is_temporary_storage_increase_enabled temporary_storage_increase_ends_on]
expect(described_class).to include_graphql_fields(*expected_fields) expect(described_class).to include_graphql_fields(*expected_fields)
end end
......
...@@ -4,4 +4,38 @@ require 'spec_helper' ...@@ -4,4 +4,38 @@ require 'spec_helper'
RSpec.describe NamespaceLimit do RSpec.describe NamespaceLimit do
it { is_expected.to belong_to(:namespace) } it { is_expected.to belong_to(:namespace) }
describe '#temporary_storage_increase_enabled?' do
let(:namespace_limit) { build(:namespace_limit) }
subject { namespace_limit.temporary_storage_increase_enabled? }
context 'when date is not set' do
it { is_expected.to eq(false) }
end
context 'when temporary storage increase end date is today' do
before do
namespace_limit.temporary_storage_increase_ends_on = Date.today
end
it { is_expected.to eq(true) }
context 'when feature is disabled' do
before do
stub_feature_flags(temporary_storage_increase: false)
end
it { is_expected.to eq(false) }
end
end
context 'when temporary storage increase end date is exceeded' do
before do
namespace_limit.temporary_storage_increase_ends_on = Date.today - 1.day
end
it { is_expected.to eq(false) }
end
end
end end
...@@ -29,6 +29,9 @@ RSpec.describe Namespace do ...@@ -29,6 +29,9 @@ RSpec.describe Namespace do
it { is_expected.to delegate_method(:additional_purchased_storage_size=).to(:namespace_limit).with_arguments(:args) } it { is_expected.to delegate_method(:additional_purchased_storage_size=).to(:namespace_limit).with_arguments(:args) }
it { is_expected.to delegate_method(:additional_purchased_storage_ends_on).to(:namespace_limit) } it { is_expected.to delegate_method(:additional_purchased_storage_ends_on).to(:namespace_limit) }
it { is_expected.to delegate_method(:additional_purchased_storage_ends_on=).to(:namespace_limit).with_arguments(:args) } it { is_expected.to delegate_method(:additional_purchased_storage_ends_on=).to(:namespace_limit).with_arguments(:args) }
it { is_expected.to delegate_method(:temporary_storage_increase_ends_on).to(:namespace_limit) }
it { is_expected.to delegate_method(:temporary_storage_increase_ends_on=).to(:namespace_limit).with_arguments(:args) }
it { is_expected.to delegate_method(:temporary_storage_increase_enabled?).to(:namespace_limit) }
shared_examples 'plan helper' do |namespace_plan| shared_examples 'plan helper' do |namespace_plan|
let(:namespace) { create(:namespace_with_plan, plan: "#{plan_name}_plan") } let(:namespace) { create(:namespace_with_plan, plan: "#{plan_name}_plan") }
......
...@@ -21,6 +21,10 @@ RSpec.describe Namespace::RootStorageSize, type: :model do ...@@ -21,6 +21,10 @@ RSpec.describe Namespace::RootStorageSize, type: :model do
describe '#above_size_limit?' do describe '#above_size_limit?' do
subject { model.above_size_limit? } subject { model.above_size_limit? }
before do
allow(namespace).to receive(:temporary_storage_increase_enabled?).and_return(false)
end
context 'when limit is 0' do context 'when limit is 0' do
let(:limit) { 0 } let(:limit) { 0 }
...@@ -34,8 +38,18 @@ RSpec.describe Namespace::RootStorageSize, type: :model do ...@@ -34,8 +38,18 @@ RSpec.describe Namespace::RootStorageSize, type: :model do
context 'when above limit' do context 'when above limit' do
let(:current_size) { 101.megabytes } let(:current_size) { 101.megabytes }
context 'when temporary storage increase is disabled' do
it { is_expected.to eq(true) } it { is_expected.to eq(true) }
end end
context 'when temporary storage increase is enabled' do
before do
allow(namespace).to receive(:temporary_storage_increase_enabled?).and_return(true)
end
it { is_expected.to eq(false) }
end
end
end end
describe '#usage_ratio' do describe '#usage_ratio' do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment