Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,4 @@ jobs:
DB_ADDRESS: localhost
DB_PORT: 3306
DB_SCHEMA: internal/database/mariadb/init/schema.sql
run: ginkgo --trace --progress -r -randomize-all -randomize-suites
run: ginkgo --trace -r -randomize-all -randomize-suites
8 changes: 6 additions & 2 deletions internal/database/mariadb/entity.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ func GetUserTypeValue(v sql.NullInt64) entity.UserType {
}
}

func IsValidId(id int64) bool {
return id > 0
}

// RowComposite is a composite type that contains all the row types for the database
// This is used to unmarshal the database rows into the corresponding entity types in a dynamical manner
type RowComposite struct {
Expand Down Expand Up @@ -1191,15 +1195,15 @@ func (rr *RemediationRow) FromRemediation(r *entity.Remediation) {
rr.Description = sql.NullString{String: r.Description, Valid: true}
rr.Type = sql.NullString{String: r.Type.String(), Valid: true}
rr.Component = sql.NullString{String: r.Component, Valid: true}
rr.ComponentId = sql.NullInt64{Int64: r.ComponentId, Valid: true}
rr.ComponentId = sql.NullInt64{Int64: r.ComponentId, Valid: IsValidId(r.ComponentId)}
rr.Service = sql.NullString{String: r.Service, Valid: true}
rr.ServiceId = sql.NullInt64{Int64: r.ServiceId, Valid: true}
rr.Issue = sql.NullString{String: r.Issue, Valid: true}
rr.IssueId = sql.NullInt64{Int64: r.IssueId, Valid: true}
rr.RemediationDate = sql.NullTime{Time: r.RemediationDate, Valid: true}
rr.ExpirationDate = sql.NullTime{Time: r.ExpirationDate, Valid: true}
rr.RemediatedBy = sql.NullString{String: r.RemediatedBy, Valid: true}
rr.RemediatedById = sql.NullInt64{Int64: r.RemediatedById, Valid: true}
rr.RemediatedById = sql.NullInt64{Int64: r.RemediatedById, Valid: IsValidId(r.RemediatedById)}
rr.CreatedAt = sql.NullTime{Time: r.CreatedAt, Valid: true}
rr.CreatedBy = sql.NullInt64{Int64: r.CreatedBy, Valid: true}
rr.DeletedAt = sql.NullTime{Time: r.DeletedAt, Valid: true}
Expand Down
90 changes: 0 additions & 90 deletions internal/database/mariadb/issue_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1180,93 +1180,3 @@ var _ = Describe("Ordering Issues", Label("IssueOrder"), func() {
})

})

var _ = Describe("Counting Issues by Severity", Label("IssueCounts"), func() {
var db *mariadb.SqlDatabase
var seeder *test.DatabaseSeeder
var seedCollection *test.SeedCollection

var testIssueSeverityCount = func(filter *entity.IssueFilter, counts entity.IssueSeverityCounts) {
issueSeverityCounts, err := db.CountIssueRatings(filter)

By("throwing no error", func() {
Expect(err).To(BeNil())
})

By("returning the correct counts", func() {
Expect(issueSeverityCounts.Critical).To(BeEquivalentTo(counts.Critical))
Expect(issueSeverityCounts.High).To(BeEquivalentTo(counts.High))
Expect(issueSeverityCounts.Medium).To(BeEquivalentTo(counts.Medium))
Expect(issueSeverityCounts.Low).To(BeEquivalentTo(counts.Low))
Expect(issueSeverityCounts.None).To(BeEquivalentTo(counts.None))
Expect(issueSeverityCounts.Total).To(BeEquivalentTo(counts.Total))
})
}

BeforeEach(func() {
var err error
db = dbm.NewTestSchema()
seeder, err = test.NewDatabaseSeeder(dbm.DbConfig())
Expect(err).To(BeNil(), "Database Seeder Setup should work")
seedCollection, err = seeder.SeedForIssueCounts()
Expect(err).To(BeNil())
err = seeder.RefreshCountIssueRatings()
Expect(err).To(BeNil())
})
AfterEach(func() {
dbm.TestTearDown(db)
})

It("returns the correct count for all issues", func() {
severityCounts, err := test.LoadIssueCounts(test.GetTestDataPath("../mariadb/testdata/issue_counts/issue_counts_per_severity.json"))
Expect(err).To(BeNil())
testIssueSeverityCount(nil, severityCounts)
})
It("returns the correct count for component version issues", func() {
severityCounts, err := test.LoadComponentVersionIssueCounts(test.GetTestDataPath("../mariadb/testdata/issue_counts/issue_counts_per_component_version.json"))
Expect(err).To(BeNil())

for _, cvi := range seedCollection.ComponentVersionIssueRows {
cvId := cvi.ComponentVersionId.Int64
filter := &entity.IssueFilter{
ComponentVersionId: []*int64{&cvId},
}

strId := fmt.Sprintf("%d", cvId)

testIssueSeverityCount(filter, severityCounts[strId])
}

})
It("returns the correct count for services", func() {
severityCounts, err := test.LoadServiceIssueCounts(test.GetTestDataPath("../mariadb/testdata/issue_counts/issue_counts_per_service.json"))
Expect(err).To(BeNil())

for _, service := range seedCollection.ServiceRows {
serviceId := service.Id.Int64

filter := &entity.IssueFilter{
ServiceId: []*int64{&serviceId},
}

strId := fmt.Sprintf("%d", serviceId)

testIssueSeverityCount(filter, severityCounts[strId])
}
})
It("returns the correct count for supportgroup", func() {
severityCounts, err := test.LoadSupportGroupIssueCounts(test.GetTestDataPath("../mariadb/testdata/issue_counts/issue_counts_per_support_group.json"))
Expect(err).To(BeNil())

for _, sg := range seedCollection.SupportGroupRows {
filter := &entity.IssueFilter{
SupportGroupCCRN: []*string{&sg.CCRN.String},
}

strId := fmt.Sprintf("%d", sg.Id.Int64)

testIssueSeverityCount(filter, severityCounts[strId])
}
})

})
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ CREATE TABLE IF NOT EXISTS mvAllComponentsByServiceVulnerabilityCounts (
CREATE PROCEDURE refresh_mvSingleComponentByServiceVulnerabilityCounts_proc()
BEGIN
-- Step 1: Create a temporary table
CREATE TABLE mvSingleComponentByServiceVulnerabilityCounts_tmp LIKE mvSingleComponentByServiceVulnerabilityCounts;
CREATE TABLE IF NOT EXISTS mvSingleComponentByServiceVulnerabilityCounts_tmp LIKE mvSingleComponentByServiceVulnerabilityCounts;
DELETE FROM mvSingleComponentByServiceVulnerabilityCounts_tmp;

-- Step 2: Populate it in a single query
Expand All @@ -55,6 +55,7 @@ BEGIN
INNER JOIN ComponentVersion AS CV ON CV.componentversion_id = CI.componentinstance_component_version_id
INNER JOIN IssueVariant AS IV ON IV.issuevariant_issue_id = IM.issuematch_issue_id
INNER JOIN Issue AS I ON I.issue_id = IV.issuevariant_issue_id
LEFT JOIN Remediation R ON CI.componentinstance_service_id = R.remediation_service_id AND I.issue_id = R.remediation_issue_id AND R.remediation_deleted_at IS NULL
WHERE
IM.issuematch_status = 'new'
AND I.issue_type = 'Vulnerability'
Expand All @@ -64,6 +65,7 @@ BEGIN
AND I.issue_deleted_at IS NULL
AND CI.componentinstance_deleted_at IS NULL
AND CV.componentversion_deleted_at IS NULL
AND (R.remediation_id IS NULL OR R.remediation_expiration_date < CURDATE())
GROUP BY
CI.componentinstance_service_id,
CV.componentversion_component_id;
Expand Down Expand Up @@ -113,6 +115,7 @@ BEGIN
ON IV.issuevariant_issue_id = IM.issuematch_issue_id
INNER JOIN Issue AS I
ON I.issue_id = IV.issuevariant_issue_id
LEFT JOIN Remediation R ON CI.componentinstance_service_id = R.remediation_service_id AND I.issue_id = R.remediation_issue_id AND R.remediation_deleted_at IS NULL
WHERE
IM.issuematch_status = 'new'
AND I.issue_type = 'Vulnerability'
Expand All @@ -121,6 +124,7 @@ BEGIN
AND I.issue_deleted_at IS NULL
AND CI.componentinstance_deleted_at IS NULL
AND CV.componentversion_deleted_at IS NULL
AND (R.remediation_id IS NULL OR R.remediation_expiration_date < CURDATE())
GROUP BY
CI.componentinstance_service_id;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,12 @@ BEGIN
LEFT JOIN IssueVariant IV ON IV.issuevariant_issue_id = I.issue_id
RIGHT JOIN IssueMatch IM ON I.issue_id = IM.issuematch_issue_id
LEFT JOIN ComponentInstance CI ON CI.componentinstance_id = IM.issuematch_component_instance_id
LEFT JOIN ComponentVersion CV ON CI.componentinstance_component_version_id = CV.componentversion_id
LEFT JOIN Service S ON S.service_id = CI.componentinstance_service_id
LEFT JOIN SupportGroupService SGS ON SGS.supportgroupservice_service_id = CI.componentinstance_service_id
LEFT JOIN SupportGroup SG ON SGS.supportgroupservice_support_group_id = SG.supportgroup_id
LEFT JOIN Remediation R ON S.service_id = R.remediation_service_id AND I.issue_id = R.remediation_issue_id AND R.remediation_deleted_at IS NULL
WHERE I.issue_deleted_at IS NULL
AND (R.remediation_id IS NULL OR R.remediation_expiration_date < CURDATE())
GROUP BY SG.supportgroup_ccrn;
END;

Expand Down Expand Up @@ -143,7 +144,9 @@ BEGIN
LEFT JOIN ComponentInstance CI ON CI.componentinstance_id = IM.issuematch_component_instance_id
LEFT JOIN ComponentVersion CV ON CI.componentinstance_component_version_id = CV.componentversion_id
LEFT JOIN Service S ON S.service_id = CI.componentinstance_service_id
WHERE I.issue_deleted_at IS NULL;
LEFT JOIN Remediation R ON S.service_id = R.remediation_service_id AND I.issue_id = R.remediation_issue_id AND R.remediation_deleted_at IS NULL
WHERE I.issue_deleted_at IS NULL
AND (R.remediation_id IS NULL OR R.remediation_expiration_date < CURDATE());
END;

--
Expand Down Expand Up @@ -204,7 +207,11 @@ BEGIN
LEFT JOIN ComponentInstance CI ON CI.componentinstance_id = IM.issuematch_component_instance_id
LEFT JOIN SupportGroupService SGS ON SGS.supportgroupservice_service_id = CI.componentinstance_service_id
LEFT JOIN SupportGroup SG ON SGS.supportgroupservice_support_group_id = SG.supportgroup_id
LEFT JOIN Remediation R ON SGS.supportgroupservice_service_id = R.remediation_service_id AND I.issue_id = R.remediation_issue_id AND R.remediation_deleted_at IS NULL
WHERE I.issue_deleted_at IS NULL
AND CI.componentinstance_deleted_at IS NULL
-- Count only non-remediated or with expired remediation
AND (R.remediation_id IS NULL OR R.remediation_expiration_date < CURDATE())
GROUP BY SG.supportgroup_ccrn;
END;

Expand All @@ -225,6 +232,7 @@ SET critical_count = CASE WHEN issue_value = 'Critical' THEN issue_count ELSE 0
none_count = CASE WHEN issue_value = 'None' THEN issue_count ELSE 0 END;

ALTER TABLE mvCountIssueRatingsComponentVersion
ADD COLUMN service_id INT DEFAULT NULL,
DROP COLUMN issue_value,
DROP COLUMN issue_count,
ADD COLUMN issue_count INT GENERATED ALWAYS AS (
Expand All @@ -237,6 +245,7 @@ BEGIN
TRUNCATE TABLE mvCountIssueRatingsComponentVersion;
INSERT INTO mvCountIssueRatingsComponentVersion (
component_version_id,
service_id,
critical_count,
high_count,
medium_count,
Expand All @@ -245,15 +254,19 @@ BEGIN
)
SELECT
CVI.componentversionissue_component_version_id AS component_version_id,
CI.componentinstance_service_id AS service_id,
COUNT(DISTINCT CASE WHEN IV.issuevariant_rating = 'Critical' THEN CONCAT(CVI.componentversionissue_component_version_id, ',', CVI.componentversionissue_issue_id) END) AS critical_count,
COUNT(DISTINCT CASE WHEN IV.issuevariant_rating = 'High' THEN CONCAT(CVI.componentversionissue_component_version_id, ',', CVI.componentversionissue_issue_id) END) AS high_count,
COUNT(DISTINCT CASE WHEN IV.issuevariant_rating = 'Medium' THEN CONCAT(CVI.componentversionissue_component_version_id, ',', CVI.componentversionissue_issue_id) END) AS medium_count,
COUNT(DISTINCT CASE WHEN IV.issuevariant_rating = 'Low' THEN CONCAT(CVI.componentversionissue_component_version_id, ',', CVI.componentversionissue_issue_id) END) AS low_count,
COUNT(DISTINCT CASE WHEN IV.issuevariant_rating = 'None' THEN CONCAT(CVI.componentversionissue_component_version_id, ',', CVI.componentversionissue_issue_id) END) AS none_count
FROM Issue I
LEFT JOIN IssueVariant IV ON IV.issuevariant_issue_id = I.issue_id
LEFT JOIN ComponentVersionIssue CVI ON I.issue_id = CVI.componentversionissue_issue_id
WHERE I.issue_deleted_at IS NULL
FROM ComponentVersionIssue CVI
LEFT JOIN IssueVariant IV ON IV.issuevariant_issue_id = CVI.componentversionissue_issue_id
INNER JOIN ComponentInstance CI ON CVI.componentversionissue_component_version_id = CI.componentinstance_component_version_id
LEFT JOIN Remediation R ON CI.componentinstance_service_id = R.remediation_service_id AND CVI.componentversionissue_issue_id = R.remediation_issue_id AND R.remediation_deleted_at IS NULL
WHERE
-- Count only non-remediated or with expired remediation
(R.remediation_id IS NULL OR R.remediation_expiration_date < CURDATE())
GROUP BY CVI.componentversionissue_component_version_id;
END;

Expand Down Expand Up @@ -302,8 +315,11 @@ BEGIN
FROM Issue I
LEFT JOIN IssueVariant IV ON IV.issuevariant_issue_id = I.issue_id
LEFT JOIN IssueMatch IM ON I.issue_id = IM.issuematch_issue_id
LEFT JOIN ComponentInstance CI ON CI.componentinstance_id = IM.issuematch_component_instance_id
LEFT JOIN ComponentInstance CI ON CI.componentinstance_id = IM.issuematch_component_instance_id AND CI.componentinstance_deleted_at IS NULL
LEFT JOIN Remediation R ON CI.componentinstance_service_id = R.remediation_service_id AND I.issue_id = R.remediation_issue_id AND R.remediation_deleted_at IS NULL
WHERE I.issue_deleted_at IS NULL
-- Count only non-remediated or with expired remediation
AND (R.remediation_id IS NULL OR R.remediation_expiration_date < CURDATE())
GROUP BY CI.componentinstance_service_id;
END;

Expand Down
Loading
Loading