Commit 5ea07326 authored by Heinrich Lee Yu's avatar Heinrich Lee Yu

Merge branch '217811-add-vulnerability-historical-statistics' into 'master'

Add Vulnerability Historical Statistics

See merge request gitlab-org/gitlab!36955
parents 11f906e9 cd913c66
# frozen_string_literal: true
class CreateVulnerabilityHistoricalStatistics < ActiveRecord::Migration[6.0]
include Gitlab::Database::MigrationHelpers
INDEX_NAME = 'index_vuln_historical_statistics_on_project_id_and_date'
DOWNTIME = false
def up
with_lock_retries do
create_table :vulnerability_historical_statistics do |t|
t.timestamps_with_timezone null: false
t.references :project, null: false, index: false, foreign_key: { on_delete: :cascade }
t.integer :total, default: 0, null: false
t.integer :critical, default: 0, null: false
t.integer :high, default: 0, null: false
t.integer :medium, default: 0, null: false
t.integer :low, default: 0, null: false
t.integer :unknown, default: 0, null: false
t.integer :info, default: 0, null: false
t.date :date, null: false
t.integer :letter_grade, limit: 1, null: false
t.index [:project_id, :date], unique: true, name: INDEX_NAME
end
end
end
def down
with_lock_retries do
drop_table :vulnerability_historical_statistics
end
end
end
......@@ -16117,6 +16117,31 @@ CREATE SEQUENCE public.vulnerability_feedback_id_seq
ALTER SEQUENCE public.vulnerability_feedback_id_seq OWNED BY public.vulnerability_feedback.id;
CREATE TABLE public.vulnerability_historical_statistics (
id bigint NOT NULL,
created_at timestamp with time zone NOT NULL,
updated_at timestamp with time zone NOT NULL,
project_id bigint NOT NULL,
total integer DEFAULT 0 NOT NULL,
critical integer DEFAULT 0 NOT NULL,
high integer DEFAULT 0 NOT NULL,
medium integer DEFAULT 0 NOT NULL,
low integer DEFAULT 0 NOT NULL,
unknown integer DEFAULT 0 NOT NULL,
info integer DEFAULT 0 NOT NULL,
date date NOT NULL,
letter_grade smallint NOT NULL
);
CREATE SEQUENCE public.vulnerability_historical_statistics_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
ALTER SEQUENCE public.vulnerability_historical_statistics_id_seq OWNED BY public.vulnerability_historical_statistics.id;
CREATE TABLE public.vulnerability_identifiers (
id bigint NOT NULL,
created_at timestamp with time zone NOT NULL,
......@@ -17112,6 +17137,8 @@ ALTER TABLE ONLY public.vulnerability_exports ALTER COLUMN id SET DEFAULT nextva
ALTER TABLE ONLY public.vulnerability_feedback ALTER COLUMN id SET DEFAULT nextval('public.vulnerability_feedback_id_seq'::regclass);
ALTER TABLE ONLY public.vulnerability_historical_statistics ALTER COLUMN id SET DEFAULT nextval('public.vulnerability_historical_statistics_id_seq'::regclass);
ALTER TABLE ONLY public.vulnerability_identifiers ALTER COLUMN id SET DEFAULT nextval('public.vulnerability_identifiers_id_seq'::regclass);
ALTER TABLE ONLY public.vulnerability_issue_links ALTER COLUMN id SET DEFAULT nextval('public.vulnerability_issue_links_id_seq'::regclass);
......@@ -18388,6 +18415,9 @@ ALTER TABLE ONLY public.vulnerability_exports
ALTER TABLE ONLY public.vulnerability_feedback
ADD CONSTRAINT vulnerability_feedback_pkey PRIMARY KEY (id);
ALTER TABLE ONLY public.vulnerability_historical_statistics
ADD CONSTRAINT vulnerability_historical_statistics_pkey PRIMARY KEY (id);
ALTER TABLE ONLY public.vulnerability_identifiers
ADD CONSTRAINT vulnerability_identifiers_pkey PRIMARY KEY (id);
......@@ -20589,6 +20619,8 @@ CREATE INDEX index_users_star_projects_on_project_id ON public.users_star_projec
CREATE UNIQUE INDEX index_users_star_projects_on_user_id_and_project_id ON public.users_star_projects USING btree (user_id, project_id);
CREATE UNIQUE INDEX index_vuln_historical_statistics_on_project_id_and_date ON public.vulnerability_historical_statistics USING btree (project_id, date);
CREATE INDEX index_vulnerabilities_on_author_id ON public.vulnerabilities USING btree (author_id);
CREATE INDEX index_vulnerabilities_on_confirmed_by_id ON public.vulnerabilities USING btree (confirmed_by_id);
......@@ -22159,6 +22191,9 @@ ALTER TABLE ONLY public.list_user_preferences
ALTER TABLE ONLY public.project_custom_attributes
ADD CONSTRAINT fk_rails_719c3dccc5 FOREIGN KEY (project_id) REFERENCES public.projects(id) ON DELETE CASCADE;
ALTER TABLE ONLY public.vulnerability_historical_statistics
ADD CONSTRAINT fk_rails_72b73ed023 FOREIGN KEY (project_id) REFERENCES public.projects(id) ON DELETE CASCADE;
ALTER TABLE ONLY public.slack_integrations
ADD CONSTRAINT fk_rails_73db19721a FOREIGN KEY (service_id) REFERENCES public.services(id) ON DELETE CASCADE;
......@@ -23945,6 +23980,7 @@ COPY "schema_migrations" (version) FROM STDIN;
20200713071042
20200713141854
20200713152443
20200715135130
20200715202659
20200716044023
20200716120419
......
......@@ -62,6 +62,7 @@ module EE
# https://gitlab.com/gitlab-org/gitlab/issues/10252#terminology
has_many :vulnerabilities
has_many :vulnerability_feedback, class_name: 'Vulnerabilities::Feedback'
has_many :vulnerability_historical_statistics, class_name: 'Vulnerabilities::HistoricalStatistic'
has_many :vulnerability_findings, class_name: 'Vulnerabilities::Occurrence' do
def lock_for_confirmation!(id)
where(vulnerability_id: nil).lock.find(id)
......
# frozen_string_literal: true
module Vulnerabilities
class HistoricalStatistic < ApplicationRecord
self.table_name = 'vulnerability_historical_statistics'
belongs_to :project, optional: false
validates :date, presence: true
validates :letter_grade, presence: true
validates :total, numericality: { greater_than_or_equal_to: 0 }
validates :critical, numericality: { greater_than_or_equal_to: 0 }
validates :high, numericality: { greater_than_or_equal_to: 0 }
validates :medium, numericality: { greater_than_or_equal_to: 0 }
validates :low, numericality: { greater_than_or_equal_to: 0 }
validates :unknown, numericality: { greater_than_or_equal_to: 0 }
validates :info, numericality: { greater_than_or_equal_to: 0 }
enum letter_grade: Vulnerabilities::Statistic.letter_grades
end
end
---
title: Add Vulnerabilities::HistoricalStatistic model
merge_request: 36955
author:
type: added
# frozen_string_literal: true
FactoryBot.define do
factory :vulnerability_historical_statistic, class: 'Vulnerabilities::HistoricalStatistic' do
project
letter_grade { 'a' }
date { Date.today }
end
end
......@@ -45,6 +45,7 @@ RSpec.describe Project do
it { is_expected.to have_many(:upstream_projects) }
it { is_expected.to have_many(:downstream_project_subscriptions) }
it { is_expected.to have_many(:downstream_projects) }
it { is_expected.to have_many(:vulnerability_historical_statistics).class_name('Vulnerabilities::HistoricalStatistic') }
it { is_expected.to have_one(:github_service) }
it { is_expected.to have_many(:project_aliases) }
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Vulnerabilities::HistoricalStatistic do
describe 'associations' do
it { is_expected.to belong_to(:project).required(true) }
end
describe 'validations' do
it { is_expected.to validate_presence_of(:date) }
it { is_expected.to validate_presence_of(:letter_grade) }
it { is_expected.to validate_numericality_of(:total).is_greater_than_or_equal_to(0) }
it { is_expected.to validate_numericality_of(:critical).is_greater_than_or_equal_to(0) }
it { is_expected.to validate_numericality_of(:high).is_greater_than_or_equal_to(0) }
it { is_expected.to validate_numericality_of(:medium).is_greater_than_or_equal_to(0) }
it { is_expected.to validate_numericality_of(:low).is_greater_than_or_equal_to(0) }
it { is_expected.to validate_numericality_of(:unknown).is_greater_than_or_equal_to(0) }
it { is_expected.to validate_numericality_of(:info).is_greater_than_or_equal_to(0) }
it { is_expected.to define_enum_for(:letter_grade).with_values(%i(a b c d f)) }
end
end
......@@ -516,6 +516,7 @@ project:
- webex_teams_service
- build_report_results
- vulnerability_statistic
- vulnerability_historical_statistics
award_emoji:
- awardable
- user
......
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