2022-07-07 20:11:50 +00:00
|
|
|
// Copyright (c) All respective contributors to the Peridot Project. All rights reserved.
|
|
|
|
// Copyright (c) 2021-2022 Rocky Enterprise Software Foundation, Inc. All rights reserved.
|
|
|
|
// Copyright (c) 2021-2022 Ctrl IQ, Inc. All rights reserved.
|
|
|
|
//
|
|
|
|
// Redistribution and use in source and binary forms, with or without
|
|
|
|
// modification, are permitted provided that the following conditions are met:
|
|
|
|
//
|
|
|
|
// 1. Redistributions of source code must retain the above copyright notice,
|
|
|
|
// this list of conditions and the following disclaimer.
|
|
|
|
//
|
|
|
|
// 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
|
|
// this list of conditions and the following disclaimer in the documentation
|
|
|
|
// and/or other materials provided with the distribution.
|
|
|
|
//
|
|
|
|
// 3. Neither the name of the copyright holder nor the names of its contributors
|
|
|
|
// may be used to endorse or promote products derived from this software without
|
|
|
|
// specific prior written permission.
|
|
|
|
//
|
|
|
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
|
|
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
|
|
|
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
|
|
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
|
|
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
|
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
|
|
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
|
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
|
|
// POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
|
2022-10-30 01:59:25 +00:00
|
|
|
package apollomock
|
2022-07-07 20:11:50 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"database/sql"
|
|
|
|
"fmt"
|
2022-10-30 01:59:25 +00:00
|
|
|
"github.com/jmoiron/sqlx/types"
|
|
|
|
apollodb "peridot.resf.org/apollo/db"
|
|
|
|
apollopb "peridot.resf.org/apollo/pb"
|
2022-07-07 20:11:50 +00:00
|
|
|
"peridot.resf.org/utils"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
|
|
|
type Access struct {
|
2022-10-30 01:59:25 +00:00
|
|
|
ShortCodes []*apollodb.ShortCode
|
|
|
|
Advisories []*apollodb.Advisory
|
|
|
|
Cves []*apollodb.CVE
|
|
|
|
Fixes []*apollodb.Fix
|
|
|
|
AdvisoryReferences []*apollodb.AdvisoryReference
|
|
|
|
Products []*apollodb.Product
|
|
|
|
AffectedProducts []*apollodb.AffectedProduct
|
|
|
|
BuildReferences []*apollodb.BuildReference
|
|
|
|
MirrorStates []*apollodb.MirrorState
|
|
|
|
AdvisoryCVEs []*apollodb.AdvisoryCVE
|
|
|
|
AdvisoryFixes []*apollodb.AdvisoryFix
|
|
|
|
IgnoredUpstreamPackages []*apollodb.IgnoredUpstreamPackage
|
|
|
|
RebootSuggestedPackages []*apollodb.RebootSuggestedPackage
|
|
|
|
AdvisoryRPMs []*apollodb.AdvisoryRPM
|
2022-07-07 20:11:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func New() *Access {
|
|
|
|
return &Access{
|
2022-10-30 01:59:25 +00:00
|
|
|
ShortCodes: []*apollodb.ShortCode{},
|
|
|
|
Advisories: []*apollodb.Advisory{},
|
|
|
|
Cves: []*apollodb.CVE{},
|
|
|
|
Fixes: []*apollodb.Fix{},
|
|
|
|
AdvisoryReferences: []*apollodb.AdvisoryReference{},
|
|
|
|
Products: []*apollodb.Product{},
|
|
|
|
AffectedProducts: []*apollodb.AffectedProduct{},
|
|
|
|
BuildReferences: []*apollodb.BuildReference{},
|
|
|
|
MirrorStates: []*apollodb.MirrorState{},
|
|
|
|
AdvisoryCVEs: []*apollodb.AdvisoryCVE{},
|
|
|
|
AdvisoryFixes: []*apollodb.AdvisoryFix{},
|
|
|
|
IgnoredUpstreamPackages: []*apollodb.IgnoredUpstreamPackage{},
|
|
|
|
RebootSuggestedPackages: []*apollodb.RebootSuggestedPackage{},
|
|
|
|
AdvisoryRPMs: []*apollodb.AdvisoryRPM{},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a *Access) GetAllShortCodes() ([]*apollodb.ShortCode, error) {
|
2022-07-07 20:11:50 +00:00
|
|
|
return a.ShortCodes, nil
|
|
|
|
}
|
|
|
|
|
2022-10-30 01:59:25 +00:00
|
|
|
func (a *Access) GetShortCodeByCode(code string) (*apollodb.ShortCode, error) {
|
2022-07-07 20:11:50 +00:00
|
|
|
for _, val := range a.ShortCodes {
|
|
|
|
if val.Code == code {
|
|
|
|
return val, nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil, sql.ErrNoRows
|
|
|
|
}
|
|
|
|
|
2022-10-30 01:59:25 +00:00
|
|
|
func (a *Access) CreateShortCode(code string, mode apollopb.ShortCode_Mode) (*apollodb.ShortCode, error) {
|
2022-07-07 20:11:50 +00:00
|
|
|
now := time.Now()
|
|
|
|
|
2022-10-30 01:59:25 +00:00
|
|
|
shortCode := apollodb.ShortCode{
|
|
|
|
Code: code,
|
|
|
|
Mode: int8(mode),
|
|
|
|
CreatedAt: &now,
|
|
|
|
ArchivedAt: sql.NullTime{},
|
2022-07-07 20:11:50 +00:00
|
|
|
}
|
|
|
|
a.ShortCodes = append(a.ShortCodes, &shortCode)
|
|
|
|
|
|
|
|
return &shortCode, nil
|
|
|
|
}
|
|
|
|
|
2022-10-30 01:59:25 +00:00
|
|
|
func (a *Access) getAdvisoriesWithJoin(filter func(*apollodb.Advisory) bool) []*apollodb.Advisory {
|
|
|
|
var advisories []*apollodb.Advisory
|
2022-07-07 20:11:50 +00:00
|
|
|
for _, val := range a.Advisories {
|
|
|
|
if filter(val) {
|
|
|
|
advisories = append(advisories, val)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(advisories) == 0 {
|
|
|
|
return advisories
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, advisory := range advisories {
|
|
|
|
advisory.AffectedProducts = []string{}
|
|
|
|
advisory.Fixes = []string{}
|
|
|
|
advisory.Cves = []string{}
|
|
|
|
advisory.References = []string{}
|
|
|
|
advisory.RPMs = []string{}
|
|
|
|
advisory.BuildArtifacts = []string{}
|
|
|
|
|
|
|
|
for _, advisoryCve := range a.AdvisoryCVEs {
|
|
|
|
if advisoryCve.AdvisoryID != advisory.ID {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, buildReference := range a.BuildReferences {
|
|
|
|
if buildReference.CveID == advisoryCve.CveID {
|
|
|
|
advisory.BuildArtifacts = append(advisory.BuildArtifacts, fmt.Sprintf("%s:::%s", buildReference.Rpm, buildReference.SrcRpm))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, cve := range a.Cves {
|
|
|
|
if cve.ID == advisoryCve.CveID {
|
|
|
|
cveString := fmt.Sprintf("%s:::%s:::%s", cve.SourceBy.String, cve.SourceLink.String, cve.ID)
|
|
|
|
if !utils.StrContains(cveString, advisory.Cves) {
|
|
|
|
advisory.Cves = append(advisory.Cves, cveString)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for _, val := range a.AffectedProducts {
|
|
|
|
if val.CveID.String == advisoryCve.CveID {
|
|
|
|
for _, product := range a.Products {
|
|
|
|
if val.ProductID == product.ID {
|
|
|
|
if !utils.StrContains(product.Name, advisory.AffectedProducts) {
|
|
|
|
advisory.AffectedProducts = append(advisory.AffectedProducts, product.Name)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, advisoryFix := range a.AdvisoryFixes {
|
|
|
|
if advisoryFix.AdvisoryID != advisory.ID {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, fix := range a.Fixes {
|
|
|
|
if fix.ID == advisoryFix.FixID {
|
|
|
|
if !utils.StrContains(fix.Ticket.String, advisory.Fixes) {
|
|
|
|
advisory.Fixes = append(advisory.Fixes, fix.Ticket.String)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, advisoryReference := range a.AdvisoryReferences {
|
|
|
|
if advisoryReference.AdvisoryId != advisory.ID {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
if !utils.StrContains(advisoryReference.URL, advisory.References) {
|
|
|
|
advisory.References = append(advisory.References, advisoryReference.URL)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, advisoryRPM := range a.AdvisoryRPMs {
|
|
|
|
if advisoryRPM.AdvisoryID != advisory.ID {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
if !utils.StrContains(advisoryRPM.Name, advisory.RPMs) {
|
|
|
|
advisory.RPMs = append(advisory.RPMs, advisoryRPM.Name)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return advisories
|
|
|
|
}
|
|
|
|
|
2022-10-30 01:59:25 +00:00
|
|
|
func (a *Access) GetAllAdvisories(filters *apollopb.AdvisoryFilters, page int32, limit int32) ([]*apollodb.Advisory, error) {
|
|
|
|
return a.getAdvisoriesWithJoin(func(advisory *apollodb.Advisory) bool {
|
|
|
|
if filters.Product != nil {
|
|
|
|
if !utils.StrContains(filters.Product.Value, advisory.AffectedProducts) {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if advisory.PublishedAt.Valid {
|
|
|
|
if filters.Before != nil {
|
|
|
|
if advisory.PublishedAt.Time.After(filters.Before.AsTime()) {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if filters.After != nil {
|
|
|
|
if advisory.PublishedAt.Time.Before(filters.After.AsTime()) {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if filters.IncludeUnpublished != nil {
|
|
|
|
if !filters.IncludeUnpublished.Value && !advisory.PublishedAt.Valid {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
} else {
|
2022-07-07 20:11:50 +00:00
|
|
|
if !advisory.PublishedAt.Valid {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-01-10 20:58:58 +00:00
|
|
|
if advisory.Fixes != nil && len(advisory.Fixes) < 1 {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2022-07-07 20:11:50 +00:00
|
|
|
return true
|
|
|
|
}), nil
|
|
|
|
}
|
|
|
|
|
2022-10-30 01:59:25 +00:00
|
|
|
func (a *Access) GetAdvisoryByCodeAndYearAndNum(code string, year int, num int) (*apollodb.Advisory, error) {
|
|
|
|
advisories := a.getAdvisoriesWithJoin(func(advisory *apollodb.Advisory) bool {
|
2022-07-07 20:11:50 +00:00
|
|
|
if advisory.ShortCodeCode == code && advisory.Year == year && advisory.Num == num {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
return false
|
|
|
|
})
|
2023-01-10 20:58:58 +00:00
|
|
|
|
2022-07-07 20:11:50 +00:00
|
|
|
if len(advisories) == 0 {
|
|
|
|
return nil, sql.ErrNoRows
|
|
|
|
}
|
|
|
|
|
2023-01-10 20:58:58 +00:00
|
|
|
advisory := advisories[0]
|
|
|
|
|
|
|
|
if advisory.Fixes != nil && len(advisory.Fixes) < 1 {
|
|
|
|
return nil, fmt.Errorf("Expected advisory fixes. Was empty.")
|
|
|
|
}
|
|
|
|
|
|
|
|
return advisory, nil
|
2022-07-07 20:11:50 +00:00
|
|
|
}
|
|
|
|
|
2022-10-30 01:59:25 +00:00
|
|
|
func (a *Access) CreateAdvisory(advisory *apollodb.Advisory) (*apollodb.Advisory, error) {
|
2022-07-07 20:11:50 +00:00
|
|
|
var lastId int64 = 1
|
|
|
|
if len(a.Advisories) > 0 {
|
|
|
|
lastId = a.Advisories[len(a.Advisories)-1].ID + 1
|
|
|
|
}
|
|
|
|
|
|
|
|
now := time.Now()
|
2022-10-30 01:59:25 +00:00
|
|
|
ret := &apollodb.Advisory{
|
2022-07-07 20:11:50 +00:00
|
|
|
ID: lastId,
|
|
|
|
CreatedAt: &now,
|
|
|
|
Year: advisory.Year,
|
|
|
|
Num: advisory.Num,
|
|
|
|
Synopsis: advisory.Synopsis,
|
|
|
|
Topic: advisory.Topic,
|
|
|
|
Severity: advisory.Severity,
|
|
|
|
Type: advisory.Type,
|
|
|
|
Description: advisory.Description,
|
|
|
|
Solution: advisory.Solution,
|
|
|
|
RedHatIssuedAt: advisory.RedHatIssuedAt,
|
|
|
|
ShortCodeCode: advisory.ShortCodeCode,
|
|
|
|
PublishedAt: advisory.PublishedAt,
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret, nil
|
|
|
|
}
|
|
|
|
|
2022-10-30 01:59:25 +00:00
|
|
|
func (a *Access) UpdateAdvisory(advisory *apollodb.Advisory) (*apollodb.Advisory, error) {
|
2022-07-07 20:11:50 +00:00
|
|
|
for _, val := range a.Advisories {
|
|
|
|
if val.ID == advisory.ID {
|
|
|
|
val.Year = advisory.Year
|
|
|
|
val.Num = advisory.Num
|
|
|
|
val.Synopsis = advisory.Synopsis
|
|
|
|
val.Topic = advisory.Topic
|
|
|
|
val.Severity = advisory.Severity
|
|
|
|
val.Type = advisory.Type
|
|
|
|
val.Description = advisory.Description
|
|
|
|
val.Solution = advisory.Solution
|
|
|
|
val.ShortCodeCode = advisory.ShortCodeCode
|
|
|
|
val.PublishedAt = advisory.PublishedAt
|
|
|
|
|
|
|
|
return val, nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil, sql.ErrNoRows
|
|
|
|
}
|
|
|
|
|
2022-10-30 01:59:25 +00:00
|
|
|
func (a *Access) GetAllUnresolvedCVEs() ([]*apollodb.CVE, error) {
|
|
|
|
var cves []*apollodb.CVE
|
|
|
|
var addedCVEIds []string
|
2022-07-07 20:11:50 +00:00
|
|
|
|
|
|
|
for _, cve := range a.Cves {
|
2022-10-30 01:59:25 +00:00
|
|
|
for _, affectedProduct := range a.AffectedProducts {
|
|
|
|
if affectedProduct.CveID.String == cve.ID {
|
|
|
|
switch affectedProduct.State {
|
|
|
|
case
|
|
|
|
int(apollopb.AffectedProduct_STATE_UNDER_INVESTIGATION_UPSTREAM),
|
|
|
|
int(apollopb.AffectedProduct_STATE_UNDER_INVESTIGATION_DOWNSTREAM),
|
|
|
|
int(apollopb.AffectedProduct_STATE_AFFECTED_UPSTREAM),
|
|
|
|
int(apollopb.AffectedProduct_STATE_AFFECTED_DOWNSTREAM):
|
|
|
|
nCve := *cve
|
|
|
|
nCve.AffectedProductId = sql.NullInt64{Valid: true, Int64: affectedProduct.ID}
|
|
|
|
cves = append(cves, &nCve)
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for _, cve := range a.Cves {
|
|
|
|
if !utils.StrContains(cve.ID, addedCVEIds) {
|
2022-07-07 20:11:50 +00:00
|
|
|
cves = append(cves, cve)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return cves, nil
|
|
|
|
}
|
|
|
|
|
2022-10-30 01:59:25 +00:00
|
|
|
func (a *Access) GetPendingAffectedProducts() ([]*apollodb.AffectedProduct, error) {
|
|
|
|
var ret []*apollodb.AffectedProduct
|
2022-07-07 20:11:50 +00:00
|
|
|
|
|
|
|
for _, affectedProduct := range a.AffectedProducts {
|
2022-10-30 01:59:25 +00:00
|
|
|
if affectedProduct.State == int(apollopb.AffectedProduct_STATE_FIXED_UPSTREAM) {
|
|
|
|
ret = append(ret, affectedProduct)
|
2022-07-07 20:11:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-10-30 01:59:25 +00:00
|
|
|
return ret, nil
|
2022-07-07 20:11:50 +00:00
|
|
|
}
|
|
|
|
|
2022-10-30 01:59:25 +00:00
|
|
|
func (a *Access) GetAllCVEsFixedDownstream() ([]*apollodb.CVE, error) {
|
|
|
|
var cves []*apollodb.CVE
|
2022-07-07 20:11:50 +00:00
|
|
|
|
|
|
|
for _, cve := range a.Cves {
|
2022-10-30 01:59:25 +00:00
|
|
|
for _, affectedProduct := range a.AffectedProducts {
|
|
|
|
if affectedProduct.CveID.String == cve.ID {
|
|
|
|
if affectedProduct.State == int(apollopb.AffectedProduct_STATE_FIXED_DOWNSTREAM) {
|
|
|
|
nCve := *cve
|
|
|
|
nCve.AffectedProductId = sql.NullInt64{Valid: true, Int64: affectedProduct.ID}
|
|
|
|
cves = append(cves, &nCve)
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
2022-07-07 20:11:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return cves, nil
|
|
|
|
}
|
|
|
|
|
2022-10-30 01:59:25 +00:00
|
|
|
func (a *Access) GetCVEByID(id string) (*apollodb.CVE, error) {
|
2022-07-07 20:11:50 +00:00
|
|
|
for _, cve := range a.Cves {
|
|
|
|
if cve.ID == id {
|
|
|
|
return cve, nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil, sql.ErrNoRows
|
|
|
|
}
|
|
|
|
|
2022-10-30 01:59:25 +00:00
|
|
|
func (a *Access) GetAllCVEs() ([]*apollodb.CVE, error) {
|
|
|
|
return a.Cves, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a *Access) CreateCVE(cveId string, shortCode string, sourceBy *string, sourceLink *string, content types.NullJSONText) (*apollodb.CVE, error) {
|
2022-07-07 20:11:50 +00:00
|
|
|
var sby sql.NullString
|
|
|
|
var sl sql.NullString
|
|
|
|
|
|
|
|
if sourceBy != nil {
|
|
|
|
sby.String = *sourceBy
|
|
|
|
sby.Valid = true
|
|
|
|
}
|
|
|
|
|
|
|
|
if sourceLink != nil {
|
|
|
|
sl.String = *sourceLink
|
|
|
|
sl.Valid = true
|
|
|
|
}
|
|
|
|
|
|
|
|
now := time.Now()
|
2022-10-30 01:59:25 +00:00
|
|
|
cve := &apollodb.CVE{
|
2022-07-07 20:11:50 +00:00
|
|
|
ID: cveId,
|
|
|
|
CreatedAt: &now,
|
|
|
|
AdvisoryId: sql.NullInt64{},
|
|
|
|
ShortCode: shortCode,
|
|
|
|
SourceBy: sby,
|
|
|
|
SourceLink: sl,
|
2022-10-30 01:59:25 +00:00
|
|
|
Content: content,
|
2022-07-07 20:11:50 +00:00
|
|
|
}
|
|
|
|
a.Cves = append(a.Cves, cve)
|
|
|
|
|
|
|
|
return cve, nil
|
|
|
|
}
|
|
|
|
|
2022-10-30 01:59:25 +00:00
|
|
|
func (a *Access) SetCVEContent(cveId string, content types.JSONText) error {
|
|
|
|
for _, cve := range a.Cves {
|
|
|
|
if cve.ID == cveId {
|
|
|
|
cve.Content = types.NullJSONText{Valid: true, JSONText: content}
|
|
|
|
return nil
|
2022-07-07 20:11:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-10-30 01:59:25 +00:00
|
|
|
return sql.ErrNoRows
|
2022-07-07 20:11:50 +00:00
|
|
|
}
|
|
|
|
|
2022-10-30 01:59:25 +00:00
|
|
|
func (a *Access) GetProductsByShortCode(code string) ([]*apollodb.Product, error) {
|
|
|
|
var products []*apollodb.Product
|
2022-07-07 20:11:50 +00:00
|
|
|
|
|
|
|
for _, product := range a.Products {
|
|
|
|
if product.ShortCode == code {
|
|
|
|
products = append(products, product)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return products, nil
|
|
|
|
}
|
|
|
|
|
2022-10-30 01:59:25 +00:00
|
|
|
func (a *Access) GetProductByNameAndShortCode(name string, code string) (*apollodb.Product, error) {
|
2022-07-07 20:11:50 +00:00
|
|
|
for _, product := range a.Products {
|
|
|
|
if product.Name == name && product.ShortCode == code {
|
|
|
|
return product, nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil, sql.ErrNoRows
|
|
|
|
}
|
|
|
|
|
2022-10-30 01:59:25 +00:00
|
|
|
func (a *Access) GetProductByID(id int64) (*apollodb.Product, error) {
|
2022-07-07 20:11:50 +00:00
|
|
|
for _, product := range a.Products {
|
|
|
|
if product.ID == id {
|
|
|
|
return product, nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil, sql.ErrNoRows
|
|
|
|
}
|
|
|
|
|
2022-10-30 01:59:25 +00:00
|
|
|
func (a *Access) CreateProduct(name string, currentFullVersion string, redHatMajorVersion *int32, code string, archs []string) (*apollodb.Product, error) {
|
2022-07-07 20:11:50 +00:00
|
|
|
var lastId int64 = 1
|
|
|
|
if len(a.Products) > 0 {
|
|
|
|
lastId = a.Products[len(a.Products)-1].ID + 1
|
|
|
|
}
|
|
|
|
|
|
|
|
var rhmv sql.NullInt32
|
|
|
|
if redHatMajorVersion != nil {
|
|
|
|
rhmv.Int32 = *redHatMajorVersion
|
|
|
|
rhmv.Valid = true
|
|
|
|
}
|
|
|
|
|
2022-10-30 01:59:25 +00:00
|
|
|
product := &apollodb.Product{
|
|
|
|
ID: lastId,
|
|
|
|
Name: name,
|
|
|
|
CurrentFullVersion: currentFullVersion,
|
|
|
|
RedHatMajorVersion: rhmv,
|
|
|
|
ShortCode: code,
|
|
|
|
Archs: archs,
|
|
|
|
MirrorFromDate: sql.NullTime{},
|
|
|
|
RedHatProductPrefix: sql.NullString{},
|
2022-07-07 20:11:50 +00:00
|
|
|
}
|
|
|
|
a.Products = append(a.Products, product)
|
|
|
|
|
|
|
|
return product, nil
|
|
|
|
}
|
|
|
|
|
2022-10-30 01:59:25 +00:00
|
|
|
func (a *Access) GetAllAffectedProductsByCVE(cve string) ([]*apollodb.AffectedProduct, error) {
|
|
|
|
var affectedProducts []*apollodb.AffectedProduct
|
2022-07-07 20:11:50 +00:00
|
|
|
|
|
|
|
for _, affectedProduct := range a.AffectedProducts {
|
|
|
|
if affectedProduct.CveID.String == cve {
|
|
|
|
affectedProducts = append(affectedProducts, affectedProduct)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return affectedProducts, nil
|
|
|
|
}
|
|
|
|
|
2022-10-30 01:59:25 +00:00
|
|
|
func (a *Access) GetAffectedProductByCVEAndPackage(cve string, pkg string) (*apollodb.AffectedProduct, error) {
|
2022-07-07 20:11:50 +00:00
|
|
|
for _, affectedProduct := range a.AffectedProducts {
|
|
|
|
if affectedProduct.CveID.String == cve && affectedProduct.Package == pkg {
|
|
|
|
return affectedProduct, nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil, sql.ErrNoRows
|
|
|
|
}
|
|
|
|
|
2022-10-30 01:59:25 +00:00
|
|
|
func (a *Access) GetAffectedProductByAdvisory(advisory string) (*apollodb.AffectedProduct, error) {
|
2022-07-07 20:11:50 +00:00
|
|
|
for _, affectedProduct := range a.AffectedProducts {
|
|
|
|
if affectedProduct.Advisory.String == advisory {
|
|
|
|
return affectedProduct, nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil, sql.ErrNoRows
|
|
|
|
}
|
|
|
|
|
2022-10-30 01:59:25 +00:00
|
|
|
func (a *Access) GetAffectedProductByID(id int64) (*apollodb.AffectedProduct, error) {
|
|
|
|
for _, affectedProduct := range a.AffectedProducts {
|
|
|
|
if affectedProduct.ID == id {
|
|
|
|
return affectedProduct, nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil, sql.ErrNoRows
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a *Access) CreateAffectedProduct(productId int64, cveId string, state int, version string, pkg string, advisory *string) (*apollodb.AffectedProduct, error) {
|
2022-07-07 20:11:50 +00:00
|
|
|
var lastId int64 = 1
|
|
|
|
if len(a.AffectedProducts) > 0 {
|
|
|
|
lastId = a.AffectedProducts[len(a.AffectedProducts)-1].ID + 1
|
|
|
|
}
|
|
|
|
|
|
|
|
var adv sql.NullString
|
|
|
|
if advisory != nil {
|
|
|
|
adv.String = *advisory
|
|
|
|
adv.Valid = true
|
|
|
|
}
|
|
|
|
|
2022-10-30 01:59:25 +00:00
|
|
|
affectedProduct := &apollodb.AffectedProduct{
|
2022-07-07 20:11:50 +00:00
|
|
|
ID: lastId,
|
|
|
|
ProductID: productId,
|
|
|
|
CveID: sql.NullString{Valid: true, String: cveId},
|
|
|
|
State: state,
|
|
|
|
Version: version,
|
|
|
|
Package: pkg,
|
|
|
|
Advisory: adv,
|
|
|
|
}
|
|
|
|
a.AffectedProducts = append(a.AffectedProducts, affectedProduct)
|
|
|
|
|
|
|
|
return affectedProduct, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a *Access) UpdateAffectedProductStateAndPackageAndAdvisory(id int64, state int, pkg string, advisory *string) error {
|
|
|
|
for _, affectedProduct := range a.AffectedProducts {
|
|
|
|
if affectedProduct.ID == id {
|
|
|
|
affectedProduct.State = state
|
|
|
|
affectedProduct.Package = pkg
|
|
|
|
|
|
|
|
var adv sql.NullString
|
|
|
|
if advisory != nil {
|
|
|
|
adv.String = *advisory
|
|
|
|
adv.Valid = true
|
|
|
|
}
|
|
|
|
affectedProduct.Advisory = adv
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return sql.ErrNoRows
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a *Access) DeleteAffectedProduct(id int64) error {
|
|
|
|
var index *int
|
|
|
|
for i, affectedProduct := range a.AffectedProducts {
|
|
|
|
if affectedProduct.ID == id {
|
|
|
|
index = &i
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if index == nil {
|
|
|
|
return sql.ErrNoRows
|
|
|
|
}
|
|
|
|
|
|
|
|
a.AffectedProducts = append(a.AffectedProducts[:*index], a.AffectedProducts[*index+1:]...)
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2022-10-30 01:59:25 +00:00
|
|
|
func (a *Access) CreateFix(ticket string, sourceBy string, sourceLink string, description string) (int64, error) {
|
2022-07-07 20:11:50 +00:00
|
|
|
var lastId int64 = 1
|
|
|
|
if len(a.Fixes) > 0 {
|
|
|
|
lastId = a.Fixes[len(a.Fixes)-1].ID + 1
|
|
|
|
}
|
|
|
|
|
2022-10-30 01:59:25 +00:00
|
|
|
fix := &apollodb.Fix{
|
2022-07-07 20:11:50 +00:00
|
|
|
ID: lastId,
|
|
|
|
Ticket: sql.NullString{Valid: true, String: ticket},
|
2022-10-30 01:59:25 +00:00
|
|
|
SourceBy: sql.NullString{Valid: true, String: sourceBy},
|
|
|
|
SourceLink: sql.NullString{Valid: true, String: sourceLink},
|
2022-07-07 20:11:50 +00:00
|
|
|
Description: sql.NullString{Valid: true, String: description},
|
|
|
|
}
|
|
|
|
a.Fixes = append(a.Fixes, fix)
|
|
|
|
|
|
|
|
return lastId, nil
|
|
|
|
}
|
|
|
|
|
2022-10-30 01:59:25 +00:00
|
|
|
func (a *Access) GetMirrorState(code string) (*apollodb.MirrorState, error) {
|
|
|
|
var lastSync *apollodb.MirrorState
|
2022-07-07 20:11:50 +00:00
|
|
|
|
|
|
|
for _, mirrorState := range a.MirrorStates {
|
|
|
|
if mirrorState.ShortCode == code {
|
|
|
|
if mirrorState.LastSync.Valid {
|
2022-10-30 01:59:25 +00:00
|
|
|
lastSync = mirrorState
|
2022-07-07 20:11:50 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if lastSync == nil {
|
|
|
|
return nil, sql.ErrNoRows
|
|
|
|
}
|
|
|
|
|
|
|
|
return lastSync, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a *Access) UpdateMirrorState(code string, lastSync *time.Time) error {
|
|
|
|
for _, mirrorState := range a.MirrorStates {
|
|
|
|
if mirrorState.ShortCode == code {
|
|
|
|
mirrorState.LastSync.Time = *lastSync
|
|
|
|
mirrorState.LastSync.Valid = true
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-10-30 01:59:25 +00:00
|
|
|
mirrorState := &apollodb.MirrorState{
|
2022-07-07 20:11:50 +00:00
|
|
|
ShortCode: code,
|
|
|
|
LastSync: sql.NullTime{Valid: true, Time: *lastSync},
|
|
|
|
}
|
|
|
|
a.MirrorStates = append(a.MirrorStates, mirrorState)
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2022-10-30 01:59:25 +00:00
|
|
|
func (a *Access) UpdateMirrorStateErrata(code string, lastSync *time.Time) error {
|
|
|
|
for _, mirrorState := range a.MirrorStates {
|
|
|
|
if mirrorState.ShortCode == code {
|
|
|
|
mirrorState.ErrataAfter.Time = *lastSync
|
|
|
|
mirrorState.ErrataAfter.Valid = true
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
mirrorState := &apollodb.MirrorState{
|
|
|
|
ShortCode: code,
|
|
|
|
ErrataAfter: sql.NullTime{Valid: true, Time: *lastSync},
|
|
|
|
}
|
|
|
|
a.MirrorStates = append(a.MirrorStates, mirrorState)
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a *Access) GetMaxLastSync() (*time.Time, error) {
|
|
|
|
var maxLastSync *time.Time
|
|
|
|
|
|
|
|
for _, mirrorState := range a.MirrorStates {
|
|
|
|
if mirrorState.LastSync.Valid {
|
|
|
|
if maxLastSync == nil || mirrorState.LastSync.Time.After(*maxLastSync) {
|
|
|
|
maxLastSync = &mirrorState.LastSync.Time
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if maxLastSync == nil {
|
|
|
|
return nil, sql.ErrNoRows
|
|
|
|
}
|
|
|
|
|
|
|
|
return maxLastSync, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a *Access) CreateBuildReference(affectedProductId int64, rpm string, srcRpm string, cveId string, sha256Sum string, kojiId *string, peridotId *string) (*apollodb.BuildReference, error) {
|
2022-07-07 20:11:50 +00:00
|
|
|
var lastId int64 = 1
|
|
|
|
if len(a.BuildReferences) > 0 {
|
|
|
|
lastId = a.BuildReferences[len(a.BuildReferences)-1].ID + 1
|
|
|
|
}
|
|
|
|
|
2022-10-30 01:59:25 +00:00
|
|
|
buildReference := &apollodb.BuildReference{
|
2022-07-07 20:11:50 +00:00
|
|
|
ID: lastId,
|
|
|
|
AffectedProductId: affectedProductId,
|
|
|
|
Rpm: rpm,
|
|
|
|
SrcRpm: srcRpm,
|
|
|
|
CveID: cveId,
|
2022-10-30 01:59:25 +00:00
|
|
|
Sha256Sum: sha256Sum,
|
|
|
|
}
|
|
|
|
if kojiId != nil {
|
|
|
|
buildReference.KojiID = sql.NullString{Valid: true, String: *kojiId}
|
|
|
|
}
|
|
|
|
if peridotId != nil {
|
|
|
|
buildReference.PeridotID = sql.NullString{Valid: true, String: *peridotId}
|
2022-07-07 20:11:50 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
a.BuildReferences = append(a.BuildReferences, buildReference)
|
|
|
|
|
|
|
|
return buildReference, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a *Access) CreateAdvisoryReference(advisoryId int64, url string) error {
|
|
|
|
var lastId int64 = 1
|
|
|
|
if len(a.AdvisoryReferences) > 0 {
|
|
|
|
lastId = a.AdvisoryReferences[len(a.AdvisoryReferences)-1].ID + 1
|
|
|
|
}
|
|
|
|
|
2022-10-30 01:59:25 +00:00
|
|
|
advisoryReference := &apollodb.AdvisoryReference{
|
2022-07-07 20:11:50 +00:00
|
|
|
ID: lastId,
|
|
|
|
URL: url,
|
|
|
|
AdvisoryId: advisoryId,
|
|
|
|
}
|
|
|
|
a.AdvisoryReferences = append(a.AdvisoryReferences, advisoryReference)
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2022-10-30 01:59:25 +00:00
|
|
|
func (a *Access) GetAllIgnoredPackagesByProductID(productID int64) ([]string, error) {
|
2022-07-07 20:11:50 +00:00
|
|
|
var packages []string
|
|
|
|
|
|
|
|
for _, ignoredPackage := range a.IgnoredUpstreamPackages {
|
2022-10-30 01:59:25 +00:00
|
|
|
if ignoredPackage.ProductID == productID {
|
2022-07-07 20:11:50 +00:00
|
|
|
packages = append(packages, ignoredPackage.Package)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return packages, nil
|
|
|
|
}
|
|
|
|
|
2022-10-30 01:59:25 +00:00
|
|
|
func (a *Access) GetAllRebootSuggestedPackages() ([]string, error) {
|
|
|
|
var packages []string
|
|
|
|
|
|
|
|
for _, p := range a.RebootSuggestedPackages {
|
|
|
|
packages = append(packages, p.Name)
|
|
|
|
}
|
|
|
|
|
|
|
|
return packages, nil
|
|
|
|
}
|
|
|
|
|
2022-07-07 20:11:50 +00:00
|
|
|
func (a *Access) AddAdvisoryFix(advisoryId int64, fixId int64) error {
|
2022-10-30 01:59:25 +00:00
|
|
|
advisoryFix := &apollodb.AdvisoryFix{
|
2022-07-07 20:11:50 +00:00
|
|
|
AdvisoryID: advisoryId,
|
|
|
|
FixID: fixId,
|
|
|
|
}
|
|
|
|
a.AdvisoryFixes = append(a.AdvisoryFixes, advisoryFix)
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a *Access) AddAdvisoryCVE(advisoryId int64, cveId string) error {
|
2022-10-30 01:59:25 +00:00
|
|
|
advisoryCVE := &apollodb.AdvisoryCVE{
|
2022-07-07 20:11:50 +00:00
|
|
|
AdvisoryID: advisoryId,
|
|
|
|
CveID: cveId,
|
|
|
|
}
|
|
|
|
a.AdvisoryCVEs = append(a.AdvisoryCVEs, advisoryCVE)
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2022-10-30 01:59:25 +00:00
|
|
|
func (a *Access) AddAdvisoryRPM(advisoryId int64, name string, productID int64) error {
|
|
|
|
advisoryRPM := &apollodb.AdvisoryRPM{
|
2022-07-07 20:11:50 +00:00
|
|
|
AdvisoryID: advisoryId,
|
|
|
|
Name: name,
|
2022-10-30 01:59:25 +00:00
|
|
|
ProductID: productID,
|
2022-07-07 20:11:50 +00:00
|
|
|
}
|
|
|
|
a.AdvisoryRPMs = append(a.AdvisoryRPMs, advisoryRPM)
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a *Access) Begin() (utils.Tx, error) {
|
|
|
|
return &utils.MockTx{}, nil
|
|
|
|
}
|
|
|
|
|
2022-10-30 01:59:25 +00:00
|
|
|
func (a *Access) UseTransaction(_ utils.Tx) apollodb.Access {
|
2022-07-07 20:11:50 +00:00
|
|
|
return a
|
|
|
|
}
|