Commit d9d73329 authored by Vijay Hawoldar's avatar Vijay Hawoldar Committed by Patrick Bair

Create table for tracking ci minute purchases

To support the development of a new way of provisioning CI Minute
purchases, we require a new table that can associate purchases to
namespaces

Changelog: added
EE: true
parent dd39fe1a
# frozen_string_literal: true
class CreateCiMinutesAdditionalPacks < ActiveRecord::Migration[6.0]
include Gitlab::Database::MigrationHelpers
def up
create_table_with_constraints :ci_minutes_additional_packs, if_not_exists: true do |t|
t.timestamps_with_timezone
t.references :namespace, index: false, null: false, foreign_key: { on_delete: :cascade }
t.date :expires_at, null: true
t.integer :number_of_minutes, null: false
t.text :purchase_xid, null: true
t.text_limit :purchase_xid, 32
t.index [:namespace_id, :purchase_xid], name: 'index_ci_minutes_additional_packs_on_namespace_id_purchase_xid'
end
end
def down
with_lock_retries do
drop_table :ci_minutes_additional_packs
end
end
end
9f3edf905be3bd3c7fe0149c9b97c68783590b808a96ad08873d983e3d901419
\ No newline at end of file
......@@ -10778,6 +10778,26 @@ CREATE SEQUENCE ci_job_variables_id_seq
ALTER SEQUENCE ci_job_variables_id_seq OWNED BY ci_job_variables.id;
CREATE TABLE ci_minutes_additional_packs (
id bigint NOT NULL,
created_at timestamp with time zone NOT NULL,
updated_at timestamp with time zone NOT NULL,
namespace_id bigint NOT NULL,
expires_at date,
number_of_minutes integer NOT NULL,
purchase_xid text,
CONSTRAINT check_d7ef254af0 CHECK ((char_length(purchase_xid) <= 32))
);
CREATE SEQUENCE ci_minutes_additional_packs_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
ALTER SEQUENCE ci_minutes_additional_packs_id_seq OWNED BY ci_minutes_additional_packs.id;
CREATE TABLE ci_namespace_monthly_usages (
id bigint NOT NULL,
namespace_id bigint NOT NULL,
......@@ -19659,6 +19679,8 @@ ALTER TABLE ONLY ci_job_artifacts ALTER COLUMN id SET DEFAULT nextval('ci_job_ar
ALTER TABLE ONLY ci_job_variables ALTER COLUMN id SET DEFAULT nextval('ci_job_variables_id_seq'::regclass);
ALTER TABLE ONLY ci_minutes_additional_packs ALTER COLUMN id SET DEFAULT nextval('ci_minutes_additional_packs_id_seq'::regclass);
ALTER TABLE ONLY ci_namespace_monthly_usages ALTER COLUMN id SET DEFAULT nextval('ci_namespace_monthly_usages_id_seq'::regclass);
ALTER TABLE ONLY ci_pending_builds ALTER COLUMN id SET DEFAULT nextval('ci_pending_builds_id_seq'::regclass);
......@@ -20840,6 +20862,9 @@ ALTER TABLE ONLY ci_job_artifacts
ALTER TABLE ONLY ci_job_variables
ADD CONSTRAINT ci_job_variables_pkey PRIMARY KEY (id);
ALTER TABLE ONLY ci_minutes_additional_packs
ADD CONSTRAINT ci_minutes_additional_packs_pkey PRIMARY KEY (id);
ALTER TABLE ONLY ci_namespace_monthly_usages
ADD CONSTRAINT ci_namespace_monthly_usages_pkey PRIMARY KEY (id);
......@@ -22770,6 +22795,8 @@ CREATE INDEX index_ci_job_variables_on_job_id ON ci_job_variables USING btree (j
CREATE UNIQUE INDEX index_ci_job_variables_on_key_and_job_id ON ci_job_variables USING btree (key, job_id);
CREATE INDEX index_ci_minutes_additional_packs_on_namespace_id_purchase_xid ON ci_minutes_additional_packs USING btree (namespace_id, purchase_xid);
CREATE UNIQUE INDEX index_ci_namespace_monthly_usages_on_namespace_id_and_date ON ci_namespace_monthly_usages USING btree (namespace_id, date);
CREATE UNIQUE INDEX index_ci_pending_builds_on_build_id ON ci_pending_builds USING btree (build_id);
......@@ -27436,6 +27463,9 @@ ALTER TABLE ONLY analytics_cycle_analytics_group_stages
ALTER TABLE ONLY bulk_import_export_uploads
ADD CONSTRAINT fk_rails_dfbfb45eca FOREIGN KEY (export_id) REFERENCES bulk_import_exports(id) ON DELETE CASCADE;
ALTER TABLE ONLY ci_minutes_additional_packs
ADD CONSTRAINT fk_rails_e0e0c4e4b1 FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE;
ALTER TABLE ONLY label_priorities
ADD CONSTRAINT fk_rails_e161058b0f FOREIGN KEY (label_id) REFERENCES labels(id) ON DELETE CASCADE;
# frozen_string_literal: true
# Representation of additional CI Minute allocations, either
# purchased via CustomersDot or assigned by an admin (self-managed)
#
# In the case of a purchase, `purchase_xid` represents the unique ID of the
# purchase via CustomersDot/Zuora
module Ci
module Minutes
class AdditionalPack < ApplicationRecord
self.table_name = 'ci_minutes_additional_packs'
belongs_to :namespace
validates :namespace, :number_of_minutes, presence: true
validates :expires_at, :purchase_xid, presence: true, if: -> { ::Gitlab.com? }
validates :purchase_xid, length: { maximum: 32 }
end
end
end
......@@ -31,6 +31,8 @@ module EE
has_many :compliance_management_frameworks, class_name: "ComplianceManagement::Framework"
has_many :ci_minutes_additional_packs, class_name: "Ci::Minutes::AdditionalPack"
accepts_nested_attributes_for :gitlab_subscription, update_only: true
accepts_nested_attributes_for :namespace_limit
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Ci::Minutes::AdditionalPack do
describe 'associations' do
it { is_expected.to belong_to(:namespace) }
end
describe 'validations' do
it { is_expected.to validate_presence_of(:namespace) }
it { is_expected.to validate_presence_of(:number_of_minutes) }
it { is_expected.to validate_length_of(:purchase_xid).is_at_most(32) }
context 'when GitLab.com' do
before do
allow(Gitlab).to receive(:com?).and_return(true)
end
it { is_expected.to validate_presence_of(:expires_at) }
it { is_expected.to validate_presence_of(:purchase_xid) }
end
context 'when self-managed' do
before do
allow(Gitlab).to receive(:com?).and_return(false)
end
it { is_expected.not_to validate_presence_of(:purchase_xid) }
it { is_expected.not_to validate_presence_of(:expires_at) }
end
end
end
......@@ -18,6 +18,7 @@ RSpec.describe Namespace do
it { is_expected.to have_one(:namespace_limit) }
it { is_expected.to have_one(:elasticsearch_indexed_namespace) }
it { is_expected.to have_one :upcoming_reconciliation }
it { is_expected.to have_many(:ci_minutes_additional_packs) }
it { is_expected.to delegate_method(:shared_runners_seconds).to(:namespace_statistics) }
it { is_expected.to delegate_method(:shared_runners_seconds_last_reset).to(:namespace_statistics) }
......
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