Commit 72422d73 authored by Mehmet Emin INAC's avatar Mehmet Emin INAC Committed by Mayra Cabrera

Prepare database for group level security exports

This commit introduces a new foreign key from vulnerability_exports to
namespaces table called `group_id` along with necessary index.
Also drops the unique aggregate index for `project_id` and `id` on
on vulnerability_exports table and introduces a new partial index for
`project_id` relation of vulnerability_exports with `is not null`
filter.
parent bacead2d
# frozen_string_literal: true
class AddGroupIdToVulnerabilityExports < ActiveRecord::Migration[6.0]
DOWNTIME = false
def change
add_column :vulnerability_exports, :group_id, :integer
change_column_null :vulnerability_exports, :project_id, true
end
end
# frozen_string_literal: true
class AddGroupIdIndexAndFkToVulnerabilityExports < ActiveRecord::Migration[6.0]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
GROUP_ID_INDEX_NAME = 'index_vulnerability_exports_on_group_id_not_null'
disable_ddl_transaction!
def up
add_concurrent_index(:vulnerability_exports, :group_id, where: 'group_id IS NOT NULL', name: GROUP_ID_INDEX_NAME)
add_concurrent_foreign_key(:vulnerability_exports, :namespaces, column: :group_id)
end
def down
remove_foreign_key(:vulnerability_exports, column: :group_id)
remove_concurrent_index_by_name(:vulnerability_exports, GROUP_ID_INDEX_NAME)
end
end
# frozen_string_literal: true
class ChangeProjectIndexOnVulnerabilityExports < ActiveRecord::Migration[6.0]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
OLD_INDEX_NAME = 'index_vulnerability_exports_on_project_id_and_id'
NEW_INDEX_NAME = 'index_vulnerability_exports_on_project_id_not_null'
disable_ddl_transaction!
def up
add_concurrent_index(:vulnerability_exports, :project_id, where: 'project_id IS NOT NULL', name: NEW_INDEX_NAME)
remove_concurrent_index_by_name(:vulnerability_exports, OLD_INDEX_NAME)
end
def down
add_concurrent_index(:vulnerability_exports, [:project_id, :id], unique: true, name: OLD_INDEX_NAME)
remove_concurrent_index_by_name(:vulnerability_exports, NEW_INDEX_NAME)
end
end
...@@ -6661,10 +6661,11 @@ CREATE TABLE public.vulnerability_exports ( ...@@ -6661,10 +6661,11 @@ CREATE TABLE public.vulnerability_exports (
finished_at timestamp with time zone, finished_at timestamp with time zone,
status character varying(255) NOT NULL, status character varying(255) NOT NULL,
file character varying(255), file character varying(255),
project_id bigint NOT NULL, project_id bigint,
author_id bigint NOT NULL, author_id bigint NOT NULL,
file_store integer, file_store integer,
format smallint DEFAULT 0 NOT NULL format smallint DEFAULT 0 NOT NULL,
group_id integer
); );
CREATE SEQUENCE public.vulnerability_exports_id_seq CREATE SEQUENCE public.vulnerability_exports_id_seq
...@@ -10446,7 +10447,9 @@ CREATE INDEX index_vulnerabilities_on_updated_by_id ON public.vulnerabilities US ...@@ -10446,7 +10447,9 @@ CREATE INDEX index_vulnerabilities_on_updated_by_id ON public.vulnerabilities US
CREATE INDEX index_vulnerability_exports_on_author_id ON public.vulnerability_exports USING btree (author_id); CREATE INDEX index_vulnerability_exports_on_author_id ON public.vulnerability_exports USING btree (author_id);
CREATE UNIQUE INDEX index_vulnerability_exports_on_project_id_and_id ON public.vulnerability_exports USING btree (project_id, id); CREATE INDEX index_vulnerability_exports_on_group_id_not_null ON public.vulnerability_exports USING btree (group_id) WHERE (group_id IS NOT NULL);
CREATE INDEX index_vulnerability_exports_on_project_id_not_null ON public.vulnerability_exports USING btree (project_id) WHERE (project_id IS NOT NULL);
CREATE INDEX index_vulnerability_feedback_on_author_id ON public.vulnerability_feedback USING btree (author_id); CREATE INDEX index_vulnerability_feedback_on_author_id ON public.vulnerability_feedback USING btree (author_id);
...@@ -10979,6 +10982,9 @@ ALTER TABLE ONLY public.design_management_versions ...@@ -10979,6 +10982,9 @@ ALTER TABLE ONLY public.design_management_versions
ALTER TABLE ONLY public.geo_event_log ALTER TABLE ONLY public.geo_event_log
ADD CONSTRAINT fk_c1f241c70d FOREIGN KEY (upload_deleted_event_id) REFERENCES public.geo_upload_deleted_events(id) ON DELETE CASCADE; ADD CONSTRAINT fk_c1f241c70d FOREIGN KEY (upload_deleted_event_id) REFERENCES public.geo_upload_deleted_events(id) ON DELETE CASCADE;
ALTER TABLE ONLY public.vulnerability_exports
ADD CONSTRAINT fk_c3d3cb5d0f FOREIGN KEY (group_id) REFERENCES public.namespaces(id) ON DELETE CASCADE;
ALTER TABLE ONLY public.geo_event_log ALTER TABLE ONLY public.geo_event_log
ADD CONSTRAINT fk_c4b1c1f66e FOREIGN KEY (repository_deleted_event_id) REFERENCES public.geo_repository_deleted_events(id) ON DELETE CASCADE; ADD CONSTRAINT fk_c4b1c1f66e FOREIGN KEY (repository_deleted_event_id) REFERENCES public.geo_repository_deleted_events(id) ON DELETE CASCADE;
...@@ -13261,6 +13267,9 @@ COPY "schema_migrations" (version) FROM STDIN; ...@@ -13261,6 +13267,9 @@ COPY "schema_migrations" (version) FROM STDIN;
20200411125656 20200411125656
20200413072059 20200413072059
20200413230056 20200413230056
20200414112444
20200414114611
20200414115801
20200414144547 20200414144547
20200415160722 20200415160722
20200415161021 20200415161021
......
...@@ -4,7 +4,8 @@ module Vulnerabilities ...@@ -4,7 +4,8 @@ module Vulnerabilities
class Export < ApplicationRecord class Export < ApplicationRecord
self.table_name = "vulnerability_exports" self.table_name = "vulnerability_exports"
belongs_to :project, optional: false belongs_to :project
belongs_to :group
belongs_to :author, optional: false, class_name: 'User' belongs_to :author, optional: false, class_name: 'User'
mount_uploader :file, AttachmentUploader mount_uploader :file, AttachmentUploader
...@@ -15,7 +16,8 @@ module Vulnerabilities ...@@ -15,7 +16,8 @@ module Vulnerabilities
csv: 0 csv: 0
} }
validates :project, presence: true validates :project, presence: true, unless: :group
validates :group, presence: true, unless: :project
validates :status, presence: true validates :status, presence: true
validates :format, presence: true validates :format, presence: true
validates :file, presence: true, if: :finished? validates :file, presence: true, if: :finished?
......
---
title: Add `group_id` column into vulnerability_exports table
merge_request: 29498
author:
type: added
...@@ -33,5 +33,10 @@ FactoryBot.define do ...@@ -33,5 +33,10 @@ FactoryBot.define do
finished_at { Time.now } finished_at { Time.now }
status { 'failed' } status { 'failed' }
end end
trait :group do
project { nil }
group
end
end end
end end
...@@ -6,7 +6,8 @@ describe Vulnerabilities::Export do ...@@ -6,7 +6,8 @@ describe Vulnerabilities::Export do
it { is_expected.to define_enum_for(:format) } it { is_expected.to define_enum_for(:format) }
describe 'associations' do describe 'associations' do
it { is_expected.to belong_to(:project).required } it { is_expected.to belong_to(:project) }
it { is_expected.to belong_to(:group) }
it { is_expected.to belong_to(:author).class_name('User').required } it { is_expected.to belong_to(:author).class_name('User').required }
end end
...@@ -22,6 +23,16 @@ describe Vulnerabilities::Export do ...@@ -22,6 +23,16 @@ describe Vulnerabilities::Export do
it { is_expected.to validate_presence_of(:file) } it { is_expected.to validate_presence_of(:file) }
end end
context 'when the group is not set' do
it { is_expected.to validate_presence_of(:project) }
end
context 'when the project is not set' do
subject { build(:vulnerability_export, :group) }
it { is_expected.to validate_presence_of(:group) }
end
end end
describe '#status' do describe '#status' 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