Sync-01 - 10/30/2022

This commit is contained in:
Mustafa Gezen 2022-10-30 02:59:25 +01:00
parent dc60de46d8
commit 6e213b3263
Signed by untrusted user who does not match committer: mustafa
GPG Key ID: DCDF010D946438C1
220 changed files with 9041 additions and 3919 deletions

View File

@ -13,11 +13,13 @@ build:inmemory --experimental_inmemory_dotd_files
# Minimize what is downloaded
build:toplevel --config=inmemory
build:toplevel --experimental_remote_download_outputs=toplevel
build:toplevel --remote_download_outputs=toplevel
build:remote --config=toplevel
build:remote --google_credentials=/tmp/credentials.json
build:remote --remote_cache=https://storage.googleapis.com/resf-temporary-bazel-cache
run:remote --experimental_remote_download_outputs=all --noexperimental_inmemory_jdeps_files --noexperimental_inmemory_dotd_files
common:ci --config=toplevel
build --stamp=true

6
.envrc.prod.mustafarocky Normal file
View File

@ -0,0 +1,6 @@
unset STABLE_LOCAL_ENVIRONMENT STABLE_OCI_REGISTRY STABLE_OCI_REGISTRY_REPO STABLE_OCI_REGISTRY_NO_NESTED_SUPPORT_IN_2022_SHAME_ON_YOU_AWS STABLE_SITE
export STABLE_STAGE="-prod"
export STABLE_REGISTRY_SECRET="none"
export STABLE_OCI_REGISTRY="docker.io"
export STABLE_OCI_REGISTRY_REPO="mustafarocky"

View File

@ -1,13 +1,12 @@
# Peridot
Named after the Gemstone, Peridot (pronounced - PERR-ih-dot) is a cloud-native build and release tool used for building, releasing and maintaining Linux distributions and forks.
# distro-tools
Cloud-native build and release tools tailored to building, releasing and maintaining Linux distributions and forks
## Structure
__Other components pending__
* publisher - `Composer for Peridot (currently only includes legacy mode)`
* peridot - `Modern build system`
* secparse - `Errata mirroring and publishing platform`
* ui - `Product Errata UI`
* apollo - `Errata mirroring and publishing platform`
* utils - `Common utilities`
* modulemd - `Modulemd parser in Go`
@ -50,6 +49,6 @@ For best experience use IntelliJ+Bazel but `govendor` creates structure that is
#### Vendor Go dependencies
`./hack/govendor`
#### Run UI in development mode
`ibazel run //TARGET:TARGET.server` - example: `ibazel run //secparse/ui:secparse.server`
`ibazel run //TARGET:TARGET.server` - example: `ibazel run //apollo/ui:apollo.server`
#### Find UI server targets
`bazel query 'attr(tags, "byc_frontend_server", //...)'`

View File

@ -0,0 +1,21 @@
load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
go_library(
name = "apollo_lib",
srcs = ["main.go"],
importpath = "peridot.resf.org/apollo/cmd/apollo",
visibility = ["//visibility:private"],
deps = [
"//apollo/db/connector",
"//apollo/impl/v1:impl",
"//utils",
"//vendor/github.com/sirupsen/logrus",
"//vendor/github.com/spf13/cobra",
],
)
go_binary(
name = "apollo",
embed = [":apollo_lib"],
visibility = ["//visibility:public"],
)

View File

@ -0,0 +1,19 @@
load("//rules_byc:defs.bzl", "BYCDEPLOY_OUTS_MIGRATE", "container", "peridot_k8s")
container(
base = "//bases/bazel/go",
files = [
"//apollo/cmd/apollo",
],
image_name = "apollo",
tars_to_layer = [
"//apollo/migrate",
],
)
peridot_k8s(
name = "apollo",
src = "deploy.jsonnet",
outs = BYCDEPLOY_OUTS_MIGRATE,
deps = ["//ci"],
)

View File

@ -0,0 +1,48 @@
local bycdeploy = import 'ci/bycdeploy.jsonnet';
local db = import 'ci/db.jsonnet';
local kubernetes = import 'ci/kubernetes.jsonnet';
local temporal = import 'ci/temporal.jsonnet';
local utils = import 'ci/utils.jsonnet';
bycdeploy.new({
name: 'apollo',
replicas: 1,
dbname: 'apollo',
backend: true,
migrate: true,
legacyDb: true,
command: '/bundle/apollo',
image: kubernetes.tag('apollo'),
tag: kubernetes.version,
dsn: {
name: 'APOLLO_DATABASE_URL',
value: db.dsn_legacy('apollo'),
},
requests: if kubernetes.prod() then {
cpu: '0.5',
memory: '512M',
},
ports: [
{
name: 'http',
containerPort: 9100,
protocol: 'TCP',
expose: true,
},
{
name: 'grpc',
containerPort: 9101,
protocol: 'TCP',
},
],
health: {
port: 9100,
},
env: [
{
name: 'APOLLO_PRODUCTION',
value: if kubernetes.dev() then 'false' else 'true',
},
$.dsn,
] + temporal.kube_env('APOLLO'),
})

View File

@ -33,30 +33,30 @@ package main
import (
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"peridot.resf.org/secparse/db/connector"
"peridot.resf.org/secparse/impl"
apolloconnector "peridot.resf.org/apollo/db/connector"
apolloimpl "peridot.resf.org/apollo/impl/v1"
"peridot.resf.org/utils"
)
var root = &cobra.Command{
Use: "secparse",
Use: "apollo",
Run: mn,
}
var cnf = utils.NewFlagConfig()
func init() {
cnf.DefaultPort = 9008
cnf.DefaultPort = 9100
dname := "secparse"
cnf.DatabaseName = &dname
cnf.Name = "secparse"
cnf.DatabaseName = utils.Pointer[string]("apollo")
cnf.Name = *cnf.DatabaseName
root.PersistentFlags().String("homepage", "https://errata.build.resf.org", "Frontend root URL")
utils.AddFlags(root.PersistentFlags(), cnf)
}
func mn(_ *cobra.Command, _ []string) {
impl.NewServer(connector.MustAuto()).Run()
apolloimpl.NewServer(apolloconnector.MustAuto()).Run()
}
func main() {

View File

@ -0,0 +1,24 @@
load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
go_library(
name = "apollostarter_lib",
srcs = ["main.go"],
importpath = "peridot.resf.org/apollo/cmd/apollostarter",
visibility = ["//visibility:private"],
deps = [
"//apollo/db/connector",
"//apollo/worker",
"//proto:common",
"//temporalutils",
"//utils",
"//vendor/github.com/sirupsen/logrus",
"//vendor/github.com/spf13/cobra",
"//vendor/go.temporal.io/sdk/client",
],
)
go_binary(
name = "apollostarter",
embed = [":apollostarter_lib"],
visibility = ["//visibility:public"],
)

View File

@ -0,0 +1,18 @@
load("//rules_byc:defs.bzl", "BYCDEPLOY_OUTS_MIGRATE", "container", "peridot_k8s")
container(
base = "//bases/bazel/go",
files = [
"//apollo/cmd/apollostarter",
],
image_name = "apollostarter",
)
peridot_k8s(
name = "apollostarter",
src = "deploy.jsonnet",
outs = BYCDEPLOY_OUTS_MIGRATE,
deps = [
"//ci",
],
)

View File

@ -0,0 +1,46 @@
local bycdeploy = import 'ci/bycdeploy.jsonnet';
local db = import 'ci/db.jsonnet';
local kubernetes = import 'ci/kubernetes.jsonnet';
local temporal = import 'ci/temporal.jsonnet';
local utils = import 'ci/utils.jsonnet';
local site = std.extVar('site');
bycdeploy.new({
name: 'apollostarter',
replicas: 1,
dbname: 'apollo',
backend: true,
migrate: true,
migrate_command: ['/bin/sh'],
migrate_args: ['-c', 'exit 0'],
legacyDb: true,
command: '/bundle/apollostarter',
image: kubernetes.tag('apollostarter'),
tag: kubernetes.version,
dsn: {
name: 'APOLLOSTARTER_DATABASE_URL',
value: db.dsn_legacy('apollo', false, 'apollostarter'),
},
requests: if kubernetes.prod() then {
cpu: '1',
memory: '2G',
},
ports: [
{
name: 'http',
containerPort: 31209,
protocol: 'TCP',
},
],
health: {
port: 31209,
},
env: [
{
name: 'APOLLOSTARTER_PRODUCTION',
value: if kubernetes.dev() then 'false' else 'true',
},
$.dsn,
] + temporal.kube_env('APOLLOSTARTER'),
})

View File

@ -0,0 +1,153 @@
// 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.
package main
import (
"context"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"go.temporal.io/sdk/client"
"log"
apolloconnector "peridot.resf.org/apollo/db/connector"
"peridot.resf.org/apollo/worker"
commonpb "peridot.resf.org/common"
"peridot.resf.org/temporalutils"
"peridot.resf.org/utils"
)
var root = &cobra.Command{
Use: "apollostarter",
Run: mn,
}
var cnf = utils.NewFlagConfig()
func init() {
cnf.DefaultPort = 31209
cnf.DatabaseName = utils.Pointer[string]("apollo")
cnf.Name = "apollostarter"
temporalutils.AddFlags(root.PersistentFlags())
utils.AddFlags(root.PersistentFlags(), cnf)
}
func mn(_ *cobra.Command, _ []string) {
c, err := temporalutils.NewClient(client.Options{})
if err != nil {
logrus.Fatalln("unable to create Temporal client", err)
}
defer c.Close()
db := apolloconnector.MustAuto()
w, err := worker.NewWorker(&worker.NewWorkerInput{
Temporal: c,
Database: db,
TaskQueue: "apollo-v1-main-queue",
})
defer w.Client.Close()
// Poll Red Hat for new CVEs and advisories every two hours
cveWfOpts := client.StartWorkflowOptions{
ID: "cron_cve_mirror",
TaskQueue: w.TaskQueue,
CronSchedule: "0 */2 * * *",
}
_, err = w.Client.ExecuteWorkflow(context.Background(), cveWfOpts, w.WorkflowController.PollRedHatCVEsWorkflow)
if err != nil {
log.Fatalf("unable to start cve workflow: %v", err)
}
errataWfOpts := client.StartWorkflowOptions{
ID: "cron_errata_mirror",
TaskQueue: w.TaskQueue,
CronSchedule: "0 */2 * * *",
}
_, err = w.Client.ExecuteWorkflow(context.Background(), errataWfOpts, w.WorkflowController.PollRedHatErrataWorkflow)
if err != nil {
log.Fatalf("unable to start errata workflow: %v", err)
}
// Poll unresolved CVE status and update every hour
cveStatusWfOpts := client.StartWorkflowOptions{
ID: "cron_cve_status",
TaskQueue: w.TaskQueue,
CronSchedule: "0 */1 * * *",
}
_, err = w.Client.ExecuteWorkflow(context.Background(), cveStatusWfOpts, w.WorkflowController.UpdateCVEStateWorkflow)
if err != nil {
log.Fatalf("unable to start cve status workflow: %v", err)
}
// Check if CVE is fixed downstream every 10 minutes
cveDownstreamWfOpts := client.StartWorkflowOptions{
ID: "cron_cve_downstream",
TaskQueue: w.TaskQueue,
CronSchedule: "*/10 * * * *",
}
_, err = w.Client.ExecuteWorkflow(context.Background(), cveDownstreamWfOpts, w.WorkflowController.DownstreamCVECheckWorkflow)
if err != nil {
log.Fatalf("unable to start cve downstream workflow: %v", err)
}
// Auto create advisory for fixed CVEs every 30 minutes
cveAdvisoryWfOpts := client.StartWorkflowOptions{
ID: "cron_cve_advisory",
TaskQueue: w.TaskQueue,
CronSchedule: "*/10 * * * *",
}
_, err = w.Client.ExecuteWorkflow(context.Background(), cveAdvisoryWfOpts, w.WorkflowController.AutoCreateAdvisoryWorkflow)
if err != nil {
log.Fatalf("unable to start cve advisory workflow: %v", err)
}
// only added so we get a health endpoint
s := utils.NewGRPCServer(
nil,
func(r *utils.Register) {
err := commonpb.RegisterHealthCheckServiceHandlerFromEndpoint(r.Context, r.Mux, r.Endpoint, r.Options)
if err != nil {
logrus.Fatalf("could not register health service: %v", err)
}
},
func(r *utils.RegisterServer) {
commonpb.RegisterHealthCheckServiceServer(r.Server, &utils.HealthServer{})
},
)
s.WaitGroup.Wait()
}
func main() {
utils.Main()
if err := root.Execute(); err != nil {
log.Fatal(err)
}
}

View File

@ -0,0 +1,27 @@
load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
go_library(
name = "apolloworker_lib",
srcs = ["main.go"],
importpath = "peridot.resf.org/apollo/cmd/apolloworker",
visibility = ["//visibility:private"],
deps = [
"//apollo/db/connector",
"//apollo/rherrata",
"//apollo/rhsecurity",
"//apollo/worker",
"//apollo/workflow",
"//proto:common",
"//temporalutils",
"//utils",
"//vendor/github.com/sirupsen/logrus",
"//vendor/github.com/spf13/cobra",
"//vendor/go.temporal.io/sdk/client",
],
)
go_binary(
name = "apolloworker",
embed = [":apolloworker_lib"],
visibility = ["//visibility:public"],
)

View File

@ -0,0 +1,18 @@
load("//rules_byc:defs.bzl", "BYCDEPLOY_OUTS_MIGRATE", "container", "peridot_k8s")
container(
base = "//bases/bazel/go",
files = [
"//apollo/cmd/apolloworker",
],
image_name = "apolloworker",
)
peridot_k8s(
name = "apolloworker",
src = "deploy.jsonnet",
outs = BYCDEPLOY_OUTS_MIGRATE,
deps = [
"//ci",
],
)

View File

@ -0,0 +1,46 @@
local bycdeploy = import 'ci/bycdeploy.jsonnet';
local db = import 'ci/db.jsonnet';
local kubernetes = import 'ci/kubernetes.jsonnet';
local temporal = import 'ci/temporal.jsonnet';
local utils = import 'ci/utils.jsonnet';
local site = std.extVar('site');
bycdeploy.new({
name: 'apolloworker',
replicas: 1,
dbname: 'apollo',
backend: true,
migrate: true,
migrate_command: ['/bin/sh'],
migrate_args: ['-c', 'exit 0'],
legacyDb: true,
command: '/bundle/apolloworker',
image: kubernetes.tag('apolloworker'),
tag: kubernetes.version,
dsn: {
name: 'APOLLOWORKER_DATABASE_URL',
value: db.dsn_legacy('apollo', false, 'apolloworker'),
},
requests: if kubernetes.prod() then {
cpu: '1',
memory: '2G',
},
ports: [
{
name: 'http',
containerPort: 29209,
protocol: 'TCP',
},
],
health: {
port: 29209,
},
env: [
{
name: 'APOLLOWORKER_PRODUCTION',
value: if kubernetes.dev() then 'false' else 'true',
},
$.dsn,
] + temporal.kube_env('APOLLOWORKER'),
})

View File

@ -0,0 +1,143 @@
// 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.
package main
import (
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"go.temporal.io/sdk/client"
"log"
apolloconnector "peridot.resf.org/apollo/db/connector"
"peridot.resf.org/apollo/rherrata"
"peridot.resf.org/apollo/rhsecurity"
"peridot.resf.org/apollo/worker"
"peridot.resf.org/apollo/workflow"
commonpb "peridot.resf.org/common"
"peridot.resf.org/temporalutils"
"peridot.resf.org/utils"
"sync"
)
var root = &cobra.Command{
Use: "apolloworker",
Run: mn,
}
var cnf = utils.NewFlagConfig()
func init() {
cnf.DefaultPort = 29209
cnf.DatabaseName = utils.Pointer[string]("apollo")
cnf.Name = "apolloworker"
pflags := root.PersistentFlags()
pflags.String("vendor", "Rocky Enterprise Software Foundation", "Vendor name that is publishing the advisories")
temporalutils.AddFlags(root.PersistentFlags())
utils.AddFlags(root.PersistentFlags(), cnf)
}
func mn(_ *cobra.Command, _ []string) {
c, err := temporalutils.NewClient(client.Options{})
if err != nil {
logrus.Fatalln("unable to create Temporal client", err)
}
defer c.Close()
db := apolloconnector.MustAuto()
options := []workflow.Option{
workflow.WithSecurityAPI(rhsecurity.NewAPIClient(rhsecurity.NewConfiguration()).DefaultApi),
workflow.WithErrataAPI(rherrata.NewClient()),
}
w, err := worker.NewWorker(
&worker.NewWorkerInput{
Temporal: c,
Database: db,
TaskQueue: "apollo-v1-main-queue",
},
options...,
)
defer w.Client.Close()
w.Worker.RegisterWorkflow(w.WorkflowController.AutoCreateAdvisoryWorkflow)
w.Worker.RegisterWorkflow(w.WorkflowController.DownstreamCVECheckWorkflow)
w.Worker.RegisterWorkflow(w.WorkflowController.PollRedHatCVEsWorkflow)
w.Worker.RegisterWorkflow(w.WorkflowController.PollRedHatErrataWorkflow)
w.Worker.RegisterWorkflow(w.WorkflowController.UpdateCVEStateWorkflow)
w.Worker.RegisterActivity(w.WorkflowController.AutoCreateAdvisoryActivity)
w.Worker.RegisterActivity(w.WorkflowController.GetAllShortCodesActivity)
w.Worker.RegisterActivity(w.WorkflowController.DownstreamCVECheckActivity)
w.Worker.RegisterActivity(w.WorkflowController.PollCVEProcessShortCodeActivity)
w.Worker.RegisterActivity(w.WorkflowController.ProcessRedHatErrataShortCodeActivity)
w.Worker.RegisterActivity(w.WorkflowController.UpdateCVEStateActivity)
w.Worker.RegisterWorkflow(w.WorkflowController.CollectCVEDataWorkflow)
w.Worker.RegisterActivity(w.WorkflowController.CollectCVEDataActivity)
var wg sync.WaitGroup
wg.Add(2)
go func() {
w.Run()
wg.Done()
}()
go func() {
// only added so we get a health endpoint
s := utils.NewGRPCServer(
nil,
func(r *utils.Register) {
err := commonpb.RegisterHealthCheckServiceHandlerFromEndpoint(r.Context, r.Mux, r.Endpoint, r.Options)
if err != nil {
logrus.Fatalf("could not register health service: %v", err)
}
},
func(r *utils.RegisterServer) {
commonpb.RegisterHealthCheckServiceServer(r.Server, &utils.HealthServer{})
},
)
s.WaitGroup.Wait()
wg.Done()
}()
wg.Wait()
}
func main() {
utils.Main()
if err := root.Execute(); err != nil {
log.Fatal(err)
}
}

View File

@ -6,13 +6,12 @@ go_library(
"convert.go",
"db.go",
],
importpath = "peridot.resf.org/secparse/db",
importpath = "peridot.resf.org/apollo/db",
visibility = ["//visibility:public"],
deps = [
"//secparse/admin/proto/v1:proto",
"//secparse/proto/v1:proto",
"//secparse/rpmutils",
"//apollo/proto/v1:pb",
"//utils",
"//vendor/github.com/jmoiron/sqlx/types",
"//vendor/github.com/lib/pq",
"@org_golang_google_protobuf//types/known/timestamppb:go_default_library",
"@org_golang_google_protobuf//types/known/wrapperspb:go_default_library",

View File

@ -3,11 +3,11 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "connector",
srcs = ["connector.go"],
importpath = "peridot.resf.org/secparse/db/connector",
importpath = "peridot.resf.org/apollo/db/connector",
visibility = ["//visibility:public"],
deps = [
"//secparse/db",
"//secparse/db/psql",
"//apollo/db",
"//apollo/db/psql",
"//utils",
"//vendor/github.com/sirupsen/logrus",
],

View File

@ -28,21 +28,21 @@
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package connector
package apolloconnector
import (
"github.com/sirupsen/logrus"
"peridot.resf.org/secparse/db"
"peridot.resf.org/secparse/db/psql"
apollodb "peridot.resf.org/apollo/db"
apollopsql "peridot.resf.org/apollo/db/psql"
"peridot.resf.org/utils"
)
// MustAuto automatically returns the correct access interface or fatally fails
func MustAuto() db.Access {
func MustAuto() apollodb.Access {
dbType := utils.GetDbType()
switch dbType {
case utils.DbPostgres:
return psql.New()
return apollopsql.New()
default:
logrus.Fatal("invalid database url supplied")
return nil

View File

@ -28,21 +28,19 @@
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package db
package apollodb
import (
"fmt"
"google.golang.org/protobuf/types/known/timestamppb"
"google.golang.org/protobuf/types/known/wrapperspb"
secparseadminpb "peridot.resf.org/secparse/admin/proto/v1"
secparsepb "peridot.resf.org/secparse/proto/v1"
"peridot.resf.org/secparse/rpmutils"
apollopb "peridot.resf.org/apollo/pb"
"strings"
)
func DTOShortCodeToPB(sc *ShortCode) *secparseadminpb.ShortCode {
ret := &secparseadminpb.ShortCode{
func DTOShortCodeToPB(sc *ShortCode) *apollopb.ShortCode {
ret := &apollopb.ShortCode{
Code: sc.Code,
Mode: secparseadminpb.ShortCodeMode(sc.Mode),
}
if sc.ArchivedAt.Valid {
@ -52,8 +50,8 @@ func DTOShortCodeToPB(sc *ShortCode) *secparseadminpb.ShortCode {
return ret
}
func DTOListShortCodesToPB(scs []*ShortCode) []*secparseadminpb.ShortCode {
var ret []*secparseadminpb.ShortCode
func DTOListShortCodesToPB(scs []*ShortCode) []*apollopb.ShortCode {
var ret []*apollopb.ShortCode
for _, v := range scs {
ret = append(ret, DTOShortCodeToPB(v))
@ -62,16 +60,16 @@ func DTOListShortCodesToPB(scs []*ShortCode) []*secparseadminpb.ShortCode {
return ret
}
func DTOAdvisoryToPB(sc *Advisory) *secparsepb.Advisory {
func DTOAdvisoryToPB(sc *Advisory) *apollopb.Advisory {
var errataType string
switch secparsepb.Advisory_Type(sc.Type) {
case secparsepb.Advisory_Security:
switch apollopb.Advisory_Type(sc.Type) {
case apollopb.Advisory_TYPE_SECURITY:
errataType = "SA"
break
case secparsepb.Advisory_BugFix:
case apollopb.Advisory_TYPE_BUGFIX:
errataType = "BA"
break
case secparsepb.Advisory_Enhancement:
case apollopb.Advisory_TYPE_ENHANCEMENT:
errataType = "EA"
break
default:
@ -84,34 +82,67 @@ func DTOAdvisoryToPB(sc *Advisory) *secparsepb.Advisory {
publishedAt = timestamppb.New(sc.PublishedAt.Time)
}
ret := &secparsepb.Advisory{
Type: secparsepb.Advisory_Type(sc.Type),
ret := &apollopb.Advisory{
Type: apollopb.Advisory_Type(sc.Type),
ShortCode: sc.ShortCodeCode,
Name: fmt.Sprintf("%s%s-%d:%d", sc.ShortCodeCode, errataType, sc.Year, sc.Num),
Synopsis: sc.Synopsis,
Severity: secparsepb.Advisory_Severity(sc.Severity),
Severity: apollopb.Advisory_Severity(sc.Severity),
Topic: sc.Topic,
Description: sc.Description,
AffectedProducts: sc.AffectedProducts,
Fixes: sc.Fixes,
Cves: sc.Cves,
Fixes: nil,
Cves: []*apollopb.CVE{},
References: sc.References,
PublishedAt: publishedAt,
Rpms: sc.RPMs,
Rpms: nil,
RebootSuggested: sc.RebootSuggested,
}
if sc.Solution.Valid {
ret.Solution = &wrapperspb.StringValue{Value: sc.Solution.String}
}
for _, cve := range sc.Cves {
split := strings.SplitN(cve, ":::", 6)
ret.Cves = append(ret.Cves, &apollopb.CVE{
Name: split[2],
SourceBy: wrapperspb.String(split[0]),
SourceLink: wrapperspb.String(split[1]),
Cvss3ScoringVector: wrapperspb.String(split[3]),
Cvss3BaseScore: wrapperspb.String(split[4]),
Cwe: wrapperspb.String(split[5]),
})
}
if len(sc.Fixes) > 0 {
ret.Fixes = []*apollopb.Fix{}
}
for _, fix := range sc.Fixes {
split := strings.SplitN(fix, ":::", 4)
ret.Fixes = append(ret.Fixes, &apollopb.Fix{
Ticket: wrapperspb.String(split[0]),
SourceBy: wrapperspb.String(split[1]),
SourceLink: wrapperspb.String(split[2]),
Description: wrapperspb.String(split[3]),
})
}
if len(sc.RPMs) > 0 {
ret.Rpms = map[string]*apollopb.RPMs{}
}
for _, rpm := range sc.RPMs {
split := strings.SplitN(rpm, ":::", 2)
nvra := split[0]
productName := split[1]
if ret.Rpms[productName] == nil {
ret.Rpms[productName] = &apollopb.RPMs{}
}
for i, rpm := range sc.RPMs {
sc.RPMs[i] = rpmutils.Epoch().ReplaceAllString(rpm, "")
ret.Rpms[productName].Nvras = append(ret.Rpms[productName].Nvras, nvra)
}
return ret
}
func DTOListAdvisoriesToPB(scs []*Advisory) []*secparsepb.Advisory {
var ret []*secparsepb.Advisory
func DTOListAdvisoriesToPB(scs []*Advisory) []*apollopb.Advisory {
var ret []*apollopb.Advisory
for _, v := range scs {
ret = append(ret, DTOAdvisoryToPB(v))
@ -120,10 +151,9 @@ func DTOListAdvisoriesToPB(scs []*Advisory) []*secparsepb.Advisory {
return ret
}
func DTOCVEToPB(cve *CVE) *secparseadminpb.CVE {
ret := &secparseadminpb.CVE{
Name: cve.ID,
State: secparseadminpb.CVEState(cve.State),
func DTOCVEToPB(cve *CVE) *apollopb.CVE {
ret := &apollopb.CVE{
Name: cve.ID,
}
if cve.SourceBy.Valid {
@ -136,8 +166,8 @@ func DTOCVEToPB(cve *CVE) *secparseadminpb.CVE {
return ret
}
func DTOListCVEsToPB(cves []*CVE) []*secparseadminpb.CVE {
var ret []*secparseadminpb.CVE
func DTOListCVEsToPB(cves []*CVE) []*apollopb.CVE {
var ret []*apollopb.CVE
for _, v := range cves {
ret = append(ret, DTOCVEToPB(v))

View File

@ -28,27 +28,26 @@
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package db
package apollodb
import (
"database/sql"
"github.com/jmoiron/sqlx/types"
"github.com/lib/pq"
secparseadminpb "peridot.resf.org/secparse/admin/proto/v1"
apollopb "peridot.resf.org/apollo/pb"
"peridot.resf.org/utils"
"time"
)
// ShortCode is the DTO struct for `resf.secparse.admin.ShortCode`
// ShortCode is the DTO struct for `resf.apollo.ShortCode`
type ShortCode struct {
Code string `db:"code"`
Mode int8 `db:"mode"`
CreatedAt *time.Time `db:"created_at"`
ArchivedAt sql.NullTime `db:"archived_at"`
MirrorFromDate sql.NullTime `db:"mirror_from_date"`
RedHatProductPrefix sql.NullString `db:"redhat_product_prefix"`
Code string `json:"code" db:"code"`
Mode int8 `json:"mode" db:"mode"`
CreatedAt *time.Time `json:"createdAt" db:"created_at"`
ArchivedAt sql.NullTime `json:"archivedAt" db:"archived_at"`
}
// Advisory is the DTO struct for `resf.secparse.Advisory`
// Advisory is the DTO struct for `resf.apollo.Advisory`
type Advisory struct {
ID int64 `db:"id"`
CreatedAt *time.Time `db:"created_at"`
@ -63,32 +62,40 @@ type Advisory struct {
Description string `db:"description"`
Solution sql.NullString `db:"solution"`
RedHatIssuedAt sql.NullTime `db:"redhat_issued_at"`
ShortCodeCode string `db:"short_code_code"`
PublishedAt sql.NullTime `db:"published_at"`
RedHatIssuedAt sql.NullTime `db:"redhat_issued_at"`
ShortCodeCode string `db:"short_code_code"`
RebootSuggested bool `db:"reboot_suggested"`
PublishedAt sql.NullTime `db:"published_at"`
AffectedProducts pq.StringArray `db:"affected_products"`
Fixes pq.StringArray `db:"fixes"`
Cves pq.StringArray `db:"cves"`
CveIds pq.StringArray `db:"cve_ids"`
References pq.StringArray `db:"references"`
RPMs pq.StringArray `db:"rpms"`
BuildArtifacts pq.StringArray `db:"build_artifacts"`
// Only used for list/search queries
Total int64 `json:"total" db:"total"`
}
// CVE is the DTO struct for `resf.secparse.admin.CVE`
// CVE is the DTO struct for `resf.apollo.CVE`
type CVE struct {
ID string `db:"id"`
CreatedAt *time.Time `db:"created_at"`
State int `db:"state"`
AdvisoryId sql.NullInt64 `db:"advisory_id"`
ShortCode string `db:"short_code_code"`
SourceBy sql.NullString `db:"source_by"`
SourceLink sql.NullString `db:"source_link"`
Content types.NullJSONText `db:"content"`
AffectedProductId sql.NullInt64 `db:"affected_product_id"`
}
// AffectedProduct is the DTO struct for `ctlriq.secparse.admin.AffectedProduct`
// AffectedProduct is the DTO struct for `resf.apollo.AffectedProduct`
type AffectedProduct struct {
ID int64 `db:"id"`
ProductID int64 `db:"product_id"`
@ -99,29 +106,43 @@ type AffectedProduct struct {
Advisory sql.NullString `db:"advisory"`
}
// Product is the DTO struct for `ctlriq.secparse.admin.Product`
// Product is the DTO struct for `resf.apollo.Product`
type Product struct {
ID int64 `db:"id"`
Name string `db:"name"`
CurrentFullVersion string `db:"current_full_version"`
RedHatMajorVersion sql.NullInt32 `db:"redhat_major_version"`
ShortCode string `db:"short_code_code"`
Archs pq.StringArray `db:"archs"`
CurrentFullVersion string `db:"current_full_version"`
RedHatMajorVersion sql.NullInt32 `db:"redhat_major_version"`
ShortCode string `db:"short_code_code"`
Archs pq.StringArray `db:"archs"`
MirrorFromDate sql.NullTime `json:"mirrorFromDate" db:"mirror_from_date"`
RedHatProductPrefix sql.NullString `json:"redHatProductPrefix" db:"redhat_product_prefix"`
Cpe sql.NullString `json:"cpe" db:"cpe"`
EolAt sql.NullTime `json:"eolAt" db:"eol_at"`
BuildSystem string `json:"buildSystem" db:"build_system"`
BuildSystemEndpoint string `json:"buildSystemEndpoint" db:"build_system_endpoint"`
KojiCompose sql.NullString `json:"kojiCompose" db:"koji_compose"`
KojiModuleCompose sql.NullString `json:"kojiModuleCompose" db:"koji_module_compose"`
PeridotProjectID sql.NullString `json:"peridotProjectID" db:"peridot_project_id"`
}
type BuildReference struct {
ID int64 `db:"id"`
AffectedProductId int64 `db:"affected_product_id"`
Rpm string `db:"rpm"`
SrcRpm string `db:"src_rpm"`
CveID string `db:"cve_id"`
KojiID string `db:"koji_id"`
ID int64 `db:"id"`
AffectedProductId int64 `db:"affected_product_id"`
Rpm string `db:"rpm"`
SrcRpm string `db:"src_rpm"`
CveID string `db:"cve_id"`
Sha256Sum string `db:"sha256_sum"`
KojiID sql.NullString `db:"koji_id"`
PeridotID sql.NullString `db:"peridot_id"`
}
type Fix struct {
ID int64 `db:"id"`
Ticket sql.NullString `db:"ticket"`
SourceBy sql.NullString `db:"source_by"`
SourceLink sql.NullString `db:"source_link"`
Description sql.NullString `db:"description"`
}
@ -132,8 +153,9 @@ type AdvisoryReference struct {
}
type MirrorState struct {
ShortCode string `db:"short_code_code"`
LastSync sql.NullTime `db:"last_sync"`
ShortCode string `db:"short_code_code"`
LastSync sql.NullTime `db:"last_sync"`
ErrataAfter sql.NullTime `db:"errata_after"`
}
type AdvisoryCVE struct {
@ -148,21 +170,27 @@ type AdvisoryFix struct {
type IgnoredUpstreamPackage struct {
ID int64 `db:"id"`
ShortCode string `db:"short_code_code"`
ProductID int64 `db:"product_id"`
Package string `db:"package"`
}
type RebootSuggestedPackage struct {
CreatedAt *time.Time `db:"created_at"`
Name string `db:"name"`
}
type AdvisoryRPM struct {
AdvisoryID int64 `db:"advisory_id"`
Name string `db:"name"`
ProductID int64 `db:"product_id"`
}
type Access interface {
GetAllShortCodes() ([]*ShortCode, error)
GetShortCodeByCode(code string) (*ShortCode, error)
CreateShortCode(code string, mode secparseadminpb.ShortCodeMode) (*ShortCode, error)
CreateShortCode(code string, mode apollopb.ShortCode_Mode) (*ShortCode, error)
GetAllAdvisories(publishedOnly bool) ([]*Advisory, error)
GetAllAdvisories(filters *apollopb.AdvisoryFilters, page int32, limit int32) ([]*Advisory, error)
// Advisory is a broad entity with lots of fields
// mustafa: It is in my opinion better to accept the same struct
// to create and update it.
@ -179,11 +207,12 @@ type Access interface {
GetAdvisoryByCodeAndYearAndNum(code string, year int, num int) (*Advisory, error)
GetAllUnresolvedCVEs() ([]*CVE, error)
GetAllCVEsWithAllProductsFixed() ([]*CVE, error)
GetPendingAffectedProducts() ([]*AffectedProduct, error)
GetAllCVEsFixedDownstream() ([]*CVE, error)
GetCVEByID(id string) (*CVE, error)
CreateCVE(cveId string, state secparseadminpb.CVEState, shortCode string, sourceBy *string, sourceLink *string) (*CVE, error)
UpdateCVEState(cve string, state secparseadminpb.CVEState) error
GetAllCVEs() ([]*CVE, error)
CreateCVE(cveId string, shortCode string, sourceBy *string, sourceLink *string, content types.NullJSONText) (*CVE, error)
SetCVEContent(cveId string, content types.JSONText) error
GetProductsByShortCode(code string) ([]*Product, error)
GetProductByNameAndShortCode(product string, code string) (*Product, error)
@ -193,25 +222,29 @@ type Access interface {
GetAllAffectedProductsByCVE(cve string) ([]*AffectedProduct, error)
GetAffectedProductByCVEAndPackage(cve string, pkg string) (*AffectedProduct, error)
GetAffectedProductByAdvisory(advisory string) (*AffectedProduct, error)
GetAffectedProductByID(id int64) (*AffectedProduct, error)
CreateAffectedProduct(productId int64, cveId string, state int, version string, pkg string, advisory *string) (*AffectedProduct, error)
UpdateAffectedProductStateAndPackageAndAdvisory(id int64, state int, pkg string, advisory *string) error
DeleteAffectedProduct(id int64) error
CreateFix(ticket string, description string) (int64, error)
CreateFix(ticket string, sourceBy string, sourceLink string, description string) (int64, error)
// This will return nil rather than an error if no rows are found
GetMirrorStateLastSync(code string) (*time.Time, error)
GetMirrorState(code string) (*MirrorState, error)
UpdateMirrorState(code string, lastSync *time.Time) error
UpdateMirrorStateErrata(code string, lastSync *time.Time) error
GetMaxLastSync() (*time.Time, error)
CreateBuildReference(affectedProductId int64, rpm string, srcRpm string, cveId string, kojiId string) (*BuildReference, error)
CreateBuildReference(affectedProductId int64, rpm string, srcRpm string, cveId string, sha256Sum string, kojiId *string, peridotId *string) (*BuildReference, error)
CreateAdvisoryReference(advisoryId int64, url string) error
GetAllIgnoredPackagesByShortCode(code string) ([]string, error)
GetAllIgnoredPackagesByProductID(productID int64) ([]string, error)
GetAllRebootSuggestedPackages() ([]string, error)
// These add methods is treated like an upsert. They're only added if one doesn't exist
AddAdvisoryFix(advisoryId int64, fixId int64) error
AddAdvisoryCVE(advisoryId int64, cveId string) error
AddAdvisoryRPM(advisoryId int64, name string) error
AddAdvisoryRPM(advisoryId int64, name string, productID int64) error
Begin() (utils.Tx, error)
UseTransaction(tx utils.Tx) Access

View File

@ -3,11 +3,12 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "mock",
srcs = ["mock.go"],
importpath = "peridot.resf.org/secparse/db/mock",
importpath = "peridot.resf.org/apollo/db/mock",
visibility = ["//visibility:public"],
deps = [
"//secparse/admin/proto/v1:proto",
"//secparse/db",
"//apollo/db",
"//apollo/proto/v1:pb",
"//utils",
"//vendor/github.com/jmoiron/sqlx/types",
],
)

View File

@ -28,56 +28,59 @@
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package mock
package apollomock
import (
"database/sql"
"fmt"
secparseadminpb "peridot.resf.org/secparse/admin/proto/v1"
"peridot.resf.org/secparse/db"
"github.com/jmoiron/sqlx/types"
apollodb "peridot.resf.org/apollo/db"
apollopb "peridot.resf.org/apollo/pb"
"peridot.resf.org/utils"
"time"
)
type Access struct {
ShortCodes []*db.ShortCode
Advisories []*db.Advisory
Cves []*db.CVE
Fixes []*db.Fix
AdvisoryReferences []*db.AdvisoryReference
Products []*db.Product
AffectedProducts []*db.AffectedProduct
BuildReferences []*db.BuildReference
MirrorStates []*db.MirrorState
AdvisoryCVEs []*db.AdvisoryCVE
AdvisoryFixes []*db.AdvisoryFix
IgnoredUpstreamPackages []*db.IgnoredUpstreamPackage
AdvisoryRPMs []*db.AdvisoryRPM
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 New() *Access {
return &Access{
ShortCodes: []*db.ShortCode{},
Advisories: []*db.Advisory{},
Cves: []*db.CVE{},
Fixes: []*db.Fix{},
AdvisoryReferences: []*db.AdvisoryReference{},
Products: []*db.Product{},
AffectedProducts: []*db.AffectedProduct{},
BuildReferences: []*db.BuildReference{},
MirrorStates: []*db.MirrorState{},
AdvisoryCVEs: []*db.AdvisoryCVE{},
AdvisoryFixes: []*db.AdvisoryFix{},
IgnoredUpstreamPackages: []*db.IgnoredUpstreamPackage{},
AdvisoryRPMs: []*db.AdvisoryRPM{},
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() ([]*db.ShortCode, error) {
func (a *Access) GetAllShortCodes() ([]*apollodb.ShortCode, error) {
return a.ShortCodes, nil
}
func (a *Access) GetShortCodeByCode(code string) (*db.ShortCode, error) {
func (a *Access) GetShortCodeByCode(code string) (*apollodb.ShortCode, error) {
for _, val := range a.ShortCodes {
if val.Code == code {
return val, nil
@ -87,24 +90,22 @@ func (a *Access) GetShortCodeByCode(code string) (*db.ShortCode, error) {
return nil, sql.ErrNoRows
}
func (a *Access) CreateShortCode(code string, mode secparseadminpb.ShortCodeMode) (*db.ShortCode, error) {
func (a *Access) CreateShortCode(code string, mode apollopb.ShortCode_Mode) (*apollodb.ShortCode, error) {
now := time.Now()
shortCode := db.ShortCode{
Code: code,
Mode: int8(mode),
CreatedAt: &now,
ArchivedAt: sql.NullTime{},
MirrorFromDate: sql.NullTime{},
RedHatProductPrefix: sql.NullString{},
shortCode := apollodb.ShortCode{
Code: code,
Mode: int8(mode),
CreatedAt: &now,
ArchivedAt: sql.NullTime{},
}
a.ShortCodes = append(a.ShortCodes, &shortCode)
return &shortCode, nil
}
func (a *Access) getAdvisoriesWithJoin(filter func(*db.Advisory) bool) []*db.Advisory {
var advisories []*db.Advisory
func (a *Access) getAdvisoriesWithJoin(filter func(*apollodb.Advisory) bool) []*apollodb.Advisory {
var advisories []*apollodb.Advisory
for _, val := range a.Advisories {
if filter(val) {
advisories = append(advisories, val)
@ -193,9 +194,30 @@ func (a *Access) getAdvisoriesWithJoin(filter func(*db.Advisory) bool) []*db.Adv
return advisories
}
func (a *Access) GetAllAdvisories(publishedOnly bool) ([]*db.Advisory, error) {
return a.getAdvisoriesWithJoin(func(advisory *db.Advisory) bool {
if publishedOnly {
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 {
if !advisory.PublishedAt.Valid {
return false
}
@ -205,8 +227,8 @@ func (a *Access) GetAllAdvisories(publishedOnly bool) ([]*db.Advisory, error) {
}), nil
}
func (a *Access) GetAdvisoryByCodeAndYearAndNum(code string, year int, num int) (*db.Advisory, error) {
advisories := a.getAdvisoriesWithJoin(func(advisory *db.Advisory) bool {
func (a *Access) GetAdvisoryByCodeAndYearAndNum(code string, year int, num int) (*apollodb.Advisory, error) {
advisories := a.getAdvisoriesWithJoin(func(advisory *apollodb.Advisory) bool {
if advisory.ShortCodeCode == code && advisory.Year == year && advisory.Num == num {
return true
}
@ -220,14 +242,14 @@ func (a *Access) GetAdvisoryByCodeAndYearAndNum(code string, year int, num int)
return advisories[0], nil
}
func (a *Access) CreateAdvisory(advisory *db.Advisory) (*db.Advisory, error) {
func (a *Access) CreateAdvisory(advisory *apollodb.Advisory) (*apollodb.Advisory, error) {
var lastId int64 = 1
if len(a.Advisories) > 0 {
lastId = a.Advisories[len(a.Advisories)-1].ID + 1
}
now := time.Now()
ret := &db.Advisory{
ret := &apollodb.Advisory{
ID: lastId,
CreatedAt: &now,
Year: advisory.Year,
@ -246,7 +268,7 @@ func (a *Access) CreateAdvisory(advisory *db.Advisory) (*db.Advisory, error) {
return ret, nil
}
func (a *Access) UpdateAdvisory(advisory *db.Advisory) (*db.Advisory, error) {
func (a *Access) UpdateAdvisory(advisory *apollodb.Advisory) (*apollodb.Advisory, error) {
for _, val := range a.Advisories {
if val.ID == advisory.ID {
val.Year = advisory.Year
@ -267,47 +289,58 @@ func (a *Access) UpdateAdvisory(advisory *db.Advisory) (*db.Advisory, error) {
return nil, sql.ErrNoRows
}
func (a *Access) GetAllUnresolvedCVEs() ([]*db.CVE, error) {
var cves []*db.CVE
func (a *Access) GetAllUnresolvedCVEs() ([]*apollodb.CVE, error) {
var cves []*apollodb.CVE
var addedCVEIds []string
for _, cve := range a.Cves {
switch cve.State {
case
int(secparseadminpb.CVEState_NewFromUpstream),
int(secparseadminpb.CVEState_NewOriginal):
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) {
cves = append(cves, cve)
break
}
}
return cves, nil
}
func (a *Access) GetAllCVEsWithAllProductsFixed() ([]*db.CVE, error) {
var cves []*db.CVE
var fixedAffectedProducts []*db.AffectedProduct
func (a *Access) GetPendingAffectedProducts() ([]*apollodb.AffectedProduct, error) {
var ret []*apollodb.AffectedProduct
for _, affectedProduct := range a.AffectedProducts {
switch affectedProduct.State {
case
int(secparseadminpb.AffectedProductState_FixedUpstream),
int(secparseadminpb.AffectedProductState_WillNotFixUpstream),
int(secparseadminpb.AffectedProductState_WillNotFixDownstream),
int(secparseadminpb.AffectedProductState_OutOfSupportScope):
fixedAffectedProducts = append(fixedAffectedProducts, affectedProduct)
if affectedProduct.State == int(apollopb.AffectedProduct_STATE_FIXED_UPSTREAM) {
ret = append(ret, affectedProduct)
}
}
return ret, nil
}
func (a *Access) GetAllCVEsFixedDownstream() ([]*apollodb.CVE, error) {
var cves []*apollodb.CVE
for _, cve := range a.Cves {
switch cve.State {
case
int(secparseadminpb.CVEState_NewFromUpstream),
int(secparseadminpb.CVEState_NewOriginal),
int(secparseadminpb.CVEState_ResolvedUpstream),
int(secparseadminpb.CVEState_ResolvedDownstream):
for _, fixed := range fixedAffectedProducts {
if fixed.CveID.String == cve.ID {
cves = append(cves, cve)
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
}
}
@ -317,19 +350,7 @@ func (a *Access) GetAllCVEsWithAllProductsFixed() ([]*db.CVE, error) {
return cves, nil
}
func (a *Access) GetAllCVEsFixedDownstream() ([]*db.CVE, error) {
var cves []*db.CVE
for _, cve := range a.Cves {
if cve.State == int(secparseadminpb.CVEState_ResolvedDownstream) {
cves = append(cves, cve)
}
}
return cves, nil
}
func (a *Access) GetCVEByID(id string) (*db.CVE, error) {
func (a *Access) GetCVEByID(id string) (*apollodb.CVE, error) {
for _, cve := range a.Cves {
if cve.ID == id {
return cve, nil
@ -339,7 +360,11 @@ func (a *Access) GetCVEByID(id string) (*db.CVE, error) {
return nil, sql.ErrNoRows
}
func (a *Access) CreateCVE(cveId string, state secparseadminpb.CVEState, shortCode string, sourceBy *string, sourceLink *string) (*db.CVE, error) {
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) {
var sby sql.NullString
var sl sql.NullString
@ -354,32 +379,33 @@ func (a *Access) CreateCVE(cveId string, state secparseadminpb.CVEState, shortCo
}
now := time.Now()
cve := &db.CVE{
cve := &apollodb.CVE{
ID: cveId,
CreatedAt: &now,
State: int(state),
AdvisoryId: sql.NullInt64{},
ShortCode: shortCode,
SourceBy: sby,
SourceLink: sl,
Content: content,
}
a.Cves = append(a.Cves, cve)
return cve, nil
}
func (a *Access) UpdateCVEState(cve string, state secparseadminpb.CVEState) error {
for _, c := range a.Cves {
if c.ID == cve {
c.State = int(state)
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
}
}
return nil
return sql.ErrNoRows
}
func (a *Access) GetProductsByShortCode(code string) ([]*db.Product, error) {
var products []*db.Product
func (a *Access) GetProductsByShortCode(code string) ([]*apollodb.Product, error) {
var products []*apollodb.Product
for _, product := range a.Products {
if product.ShortCode == code {
@ -390,7 +416,7 @@ func (a *Access) GetProductsByShortCode(code string) ([]*db.Product, error) {
return products, nil
}
func (a *Access) GetProductByNameAndShortCode(name string, code string) (*db.Product, error) {
func (a *Access) GetProductByNameAndShortCode(name string, code string) (*apollodb.Product, error) {
for _, product := range a.Products {
if product.Name == name && product.ShortCode == code {
return product, nil
@ -400,7 +426,7 @@ func (a *Access) GetProductByNameAndShortCode(name string, code string) (*db.Pro
return nil, sql.ErrNoRows
}
func (a *Access) GetProductByID(id int64) (*db.Product, error) {
func (a *Access) GetProductByID(id int64) (*apollodb.Product, error) {
for _, product := range a.Products {
if product.ID == id {
return product, nil
@ -410,7 +436,7 @@ func (a *Access) GetProductByID(id int64) (*db.Product, error) {
return nil, sql.ErrNoRows
}
func (a *Access) CreateProduct(name string, currentFullVersion string, redHatMajorVersion *int32, code string, archs []string) (*db.Product, error) {
func (a *Access) CreateProduct(name string, currentFullVersion string, redHatMajorVersion *int32, code string, archs []string) (*apollodb.Product, error) {
var lastId int64 = 1
if len(a.Products) > 0 {
lastId = a.Products[len(a.Products)-1].ID + 1
@ -422,21 +448,23 @@ func (a *Access) CreateProduct(name string, currentFullVersion string, redHatMaj
rhmv.Valid = true
}
product := &db.Product{
ID: lastId,
Name: name,
CurrentFullVersion: currentFullVersion,
RedHatMajorVersion: rhmv,
ShortCode: code,
Archs: archs,
product := &apollodb.Product{
ID: lastId,
Name: name,
CurrentFullVersion: currentFullVersion,
RedHatMajorVersion: rhmv,
ShortCode: code,
Archs: archs,
MirrorFromDate: sql.NullTime{},
RedHatProductPrefix: sql.NullString{},
}
a.Products = append(a.Products, product)
return product, nil
}
func (a *Access) GetAllAffectedProductsByCVE(cve string) ([]*db.AffectedProduct, error) {
var affectedProducts []*db.AffectedProduct
func (a *Access) GetAllAffectedProductsByCVE(cve string) ([]*apollodb.AffectedProduct, error) {
var affectedProducts []*apollodb.AffectedProduct
for _, affectedProduct := range a.AffectedProducts {
if affectedProduct.CveID.String == cve {
@ -447,7 +475,7 @@ func (a *Access) GetAllAffectedProductsByCVE(cve string) ([]*db.AffectedProduct,
return affectedProducts, nil
}
func (a *Access) GetAffectedProductByCVEAndPackage(cve string, pkg string) (*db.AffectedProduct, error) {
func (a *Access) GetAffectedProductByCVEAndPackage(cve string, pkg string) (*apollodb.AffectedProduct, error) {
for _, affectedProduct := range a.AffectedProducts {
if affectedProduct.CveID.String == cve && affectedProduct.Package == pkg {
return affectedProduct, nil
@ -457,7 +485,7 @@ func (a *Access) GetAffectedProductByCVEAndPackage(cve string, pkg string) (*db.
return nil, sql.ErrNoRows
}
func (a *Access) GetAffectedProductByAdvisory(advisory string) (*db.AffectedProduct, error) {
func (a *Access) GetAffectedProductByAdvisory(advisory string) (*apollodb.AffectedProduct, error) {
for _, affectedProduct := range a.AffectedProducts {
if affectedProduct.Advisory.String == advisory {
return affectedProduct, nil
@ -467,7 +495,17 @@ func (a *Access) GetAffectedProductByAdvisory(advisory string) (*db.AffectedProd
return nil, sql.ErrNoRows
}
func (a *Access) CreateAffectedProduct(productId int64, cveId string, state int, version string, pkg string, advisory *string) (*db.AffectedProduct, error) {
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) {
var lastId int64 = 1
if len(a.AffectedProducts) > 0 {
lastId = a.AffectedProducts[len(a.AffectedProducts)-1].ID + 1
@ -479,7 +517,7 @@ func (a *Access) CreateAffectedProduct(productId int64, cveId string, state int,
adv.Valid = true
}
affectedProduct := &db.AffectedProduct{
affectedProduct := &apollodb.AffectedProduct{
ID: lastId,
ProductID: productId,
CveID: sql.NullString{Valid: true, String: cveId},
@ -529,15 +567,17 @@ func (a *Access) DeleteAffectedProduct(id int64) error {
return nil
}
func (a *Access) CreateFix(ticket string, description string) (int64, error) {
func (a *Access) CreateFix(ticket string, sourceBy string, sourceLink string, description string) (int64, error) {
var lastId int64 = 1
if len(a.Fixes) > 0 {
lastId = a.Fixes[len(a.Fixes)-1].ID + 1
}
fix := &db.Fix{
fix := &apollodb.Fix{
ID: lastId,
Ticket: sql.NullString{Valid: true, String: ticket},
SourceBy: sql.NullString{Valid: true, String: sourceBy},
SourceLink: sql.NullString{Valid: true, String: sourceLink},
Description: sql.NullString{Valid: true, String: description},
}
a.Fixes = append(a.Fixes, fix)
@ -545,13 +585,13 @@ func (a *Access) CreateFix(ticket string, description string) (int64, error) {
return lastId, nil
}
func (a *Access) GetMirrorStateLastSync(code string) (*time.Time, error) {
var lastSync *time.Time
func (a *Access) GetMirrorState(code string) (*apollodb.MirrorState, error) {
var lastSync *apollodb.MirrorState
for _, mirrorState := range a.MirrorStates {
if mirrorState.ShortCode == code {
if mirrorState.LastSync.Valid {
lastSync = &mirrorState.LastSync.Time
lastSync = mirrorState
}
}
}
@ -573,7 +613,7 @@ func (a *Access) UpdateMirrorState(code string, lastSync *time.Time) error {
}
}
mirrorState := &db.MirrorState{
mirrorState := &apollodb.MirrorState{
ShortCode: code,
LastSync: sql.NullTime{Valid: true, Time: *lastSync},
}
@ -582,19 +622,62 @@ func (a *Access) UpdateMirrorState(code string, lastSync *time.Time) error {
return nil
}
func (a *Access) CreateBuildReference(affectedProductId int64, rpm string, srcRpm string, cveId string, kojiId string) (*db.BuildReference, error) {
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) {
var lastId int64 = 1
if len(a.BuildReferences) > 0 {
lastId = a.BuildReferences[len(a.BuildReferences)-1].ID + 1
}
buildReference := &db.BuildReference{
buildReference := &apollodb.BuildReference{
ID: lastId,
AffectedProductId: affectedProductId,
Rpm: rpm,
SrcRpm: srcRpm,
CveID: cveId,
KojiID: kojiId,
Sha256Sum: sha256Sum,
}
if kojiId != nil {
buildReference.KojiID = sql.NullString{Valid: true, String: *kojiId}
}
if peridotId != nil {
buildReference.PeridotID = sql.NullString{Valid: true, String: *peridotId}
}
a.BuildReferences = append(a.BuildReferences, buildReference)
@ -608,7 +691,7 @@ func (a *Access) CreateAdvisoryReference(advisoryId int64, url string) error {
lastId = a.AdvisoryReferences[len(a.AdvisoryReferences)-1].ID + 1
}
advisoryReference := &db.AdvisoryReference{
advisoryReference := &apollodb.AdvisoryReference{
ID: lastId,
URL: url,
AdvisoryId: advisoryId,
@ -618,11 +701,11 @@ func (a *Access) CreateAdvisoryReference(advisoryId int64, url string) error {
return nil
}
func (a *Access) GetAllIgnoredPackagesByShortCode(code string) ([]string, error) {
func (a *Access) GetAllIgnoredPackagesByProductID(productID int64) ([]string, error) {
var packages []string
for _, ignoredPackage := range a.IgnoredUpstreamPackages {
if ignoredPackage.ShortCode == code {
if ignoredPackage.ProductID == productID {
packages = append(packages, ignoredPackage.Package)
}
}
@ -630,8 +713,18 @@ func (a *Access) GetAllIgnoredPackagesByShortCode(code string) ([]string, error)
return packages, nil
}
func (a *Access) GetAllRebootSuggestedPackages() ([]string, error) {
var packages []string
for _, p := range a.RebootSuggestedPackages {
packages = append(packages, p.Name)
}
return packages, nil
}
func (a *Access) AddAdvisoryFix(advisoryId int64, fixId int64) error {
advisoryFix := &db.AdvisoryFix{
advisoryFix := &apollodb.AdvisoryFix{
AdvisoryID: advisoryId,
FixID: fixId,
}
@ -641,7 +734,7 @@ func (a *Access) AddAdvisoryFix(advisoryId int64, fixId int64) error {
}
func (a *Access) AddAdvisoryCVE(advisoryId int64, cveId string) error {
advisoryCVE := &db.AdvisoryCVE{
advisoryCVE := &apollodb.AdvisoryCVE{
AdvisoryID: advisoryId,
CveID: cveId,
}
@ -650,10 +743,11 @@ func (a *Access) AddAdvisoryCVE(advisoryId int64, cveId string) error {
return nil
}
func (a *Access) AddAdvisoryRPM(advisoryId int64, name string) error {
advisoryRPM := &db.AdvisoryRPM{
func (a *Access) AddAdvisoryRPM(advisoryId int64, name string, productID int64) error {
advisoryRPM := &apollodb.AdvisoryRPM{
AdvisoryID: advisoryId,
Name: name,
ProductID: productID,
}
a.AdvisoryRPMs = append(a.AdvisoryRPMs, advisoryRPM)
@ -664,6 +758,6 @@ func (a *Access) Begin() (utils.Tx, error) {
return &utils.MockTx{}, nil
}
func (a *Access) UseTransaction(_ utils.Tx) db.Access {
func (a *Access) UseTransaction(_ utils.Tx) apollodb.Access {
return a
}

View File

@ -3,12 +3,13 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "psql",
srcs = ["psql.go"],
importpath = "peridot.resf.org/secparse/db/psql",
importpath = "peridot.resf.org/apollo/db/psql",
visibility = ["//visibility:public"],
deps = [
"//secparse/admin/proto/v1:proto",
"//secparse/db",
"//apollo/db",
"//apollo/proto/v1:pb",
"//utils",
"//vendor/github.com/jmoiron/sqlx",
"//vendor/github.com/jmoiron/sqlx/types",
],
)

802
apollo/db/psql/psql.go Normal file
View File

@ -0,0 +1,802 @@
// 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.
package apollopsql
import (
"database/sql"
"github.com/jmoiron/sqlx/types"
apollodb "peridot.resf.org/apollo/db"
apollopb "peridot.resf.org/apollo/pb"
"time"
"github.com/jmoiron/sqlx"
"peridot.resf.org/utils"
)
type Access struct {
db *sqlx.DB
query utils.SqlQuery
}
func New() *Access {
pgx := utils.PgInitx()
return &Access{
db: pgx,
query: pgx,
}
}
func (a *Access) GetAllShortCodes() ([]*apollodb.ShortCode, error) {
var shortCodes []*apollodb.ShortCode
err := a.query.Select(
&shortCodes,
`
select
code,
mode,
created_at,
archived_at
from short_codes
order by created_at desc
`,
)
if err != nil {
return nil, err
}
return shortCodes, nil
}
func (a *Access) GetShortCodeByCode(code string) (*apollodb.ShortCode, error) {
var shortCode apollodb.ShortCode
err := a.query.Get(&shortCode, "select code, mode, created_at from short_codes where code = $1", code)
if err != nil {
return nil, err
}
return &shortCode, nil
}
func (a *Access) CreateShortCode(code string, mode apollopb.ShortCode_Mode) (*apollodb.ShortCode, error) {
var shortCode apollodb.ShortCode
err := a.query.Get(&shortCode, "insert into short_codes (code, mode) values ($1, $2) returning code, mode, created_at", code, int(mode))
if err != nil {
return nil, err
}
return &shortCode, nil
}
func (a *Access) GetAllAdvisories(filters *apollopb.AdvisoryFilters, page int32, limit int32) ([]*apollodb.Advisory, error) {
if filters == nil {
filters = &apollopb.AdvisoryFilters{}
}
var advisories []*apollodb.Advisory
err := a.query.Select(
&advisories,
`
select
q1.*
from
(
select
a.id,
a.created_at,
a.year,
a.num,
a.synopsis,
a.topic,
a.severity,
a.type,
a.description,
a.solution,
a.redhat_issued_at,
a.short_code_code,
a.reboot_suggested,
a.published_at,
array_remove(array_agg(distinct p.name), NULL) as affected_products,
(select array_agg(distinct(
case when c.content is null then c.source_by || ':::' || c.source_link || ':::' || c.id || ':::::::::'
else c.source_by || ':::' || c.source_link || ':::' || c.id || ':::' || jsonb_extract_path_text(c.content, 'cvss3', 'cvss3_scoring_vector') || ':::' || jsonb_extract_path_text(c.content, 'cvss3', 'cvss3_base_score') || ':::' || jsonb_extract_path_text(c.content, 'cwe')
end
)) from advisory_cves ac inner join cves c on c.id = ac.cve_id where ac.advisory_id = a.id) as cves,
(select array_agg(distinct(url)) from advisory_references where advisory_id = a.id) as references,
case when $4 :: bool = true then array(select distinct concat(rpm, ':::', src_rpm) from build_references where affected_product_id in (select id from affected_products where advisory = 'RH' || (case when a.type=1 then 'SA' when a.type=2 then 'BA' else 'EA' end) || '-' || a.year || ':' || a.num))
else array [] :: text[]
end as build_artifacts,
case when $7 :: bool = true then array(select distinct(ar.name || ':::' || p.name) from advisory_rpms ar inner join products p on p.id = ar.product_id where advisory_id = a.id)
else array [] :: text[]
end as rpms,
count(a.*) over() as total
from advisories a
inner join affected_products ap on ap.advisory = 'RH' || (case when a.type=1 then 'SA' when a.type=2 then 'BA' else 'EA' end) || '-' || a.year || ':' || a.num
inner join products p on ap.product_id = p.id
where
($1 :: text is null or p.name = $1 :: text)
and ($2 :: timestamp is null or a.published_at < $2 :: timestamp)
and ($3 :: timestamp is null or a.published_at > $3 :: timestamp)
and (a.published_at is not null or $4 :: bool = true)
and ($6 :: text is null or a.synopsis ilike '%' || $6 :: text || '%')
and ($9 :: numeric = 0 or a.severity = $9 :: numeric)
and ($10 :: numeric = 0 or a.type = $10 :: numeric)
group by a.id
order by a.published_at desc
limit $11 offset $12
) as q1
where
($8 :: text is null or ((q1.synopsis ilike '%' || $8 :: text || '%') or (q1.topic ilike '%' || $8 :: text || '%') or (q1.description ilike '%' || $8 :: text || '%') or (q1.solution ilike '%' || $8 :: text || '%') or exists (select from unnest(q1.cves) e where e ilike '%' || $8 :: text || '%')))
and ($5 :: text is null or exists (select from unnest(q1.cves) e where e ilike '%' || $5 :: text || '%'))
`,
utils.StringValueToNullString(filters.Product),
utils.TimestampToNullTime(filters.Before),
utils.TimestampToNullTime(filters.After),
utils.BoolValueP(filters.IncludeUnpublished),
utils.StringValueToNullString(filters.Cve),
utils.StringValueToNullString(filters.Synopsis),
utils.BoolValueP(filters.IncludeRpms),
utils.StringValueToNullString(filters.Keyword),
int32(filters.Severity),
int32(filters.Type),
utils.UnlimitedLimit(limit),
utils.GetOffset(page, limit),
)
if err != nil {
return nil, err
}
return advisories, nil
}
func (a *Access) GetAdvisoryByCodeAndYearAndNum(code string, year int, num int) (*apollodb.Advisory, error) {
var advisory apollodb.Advisory
err := a.query.Get(
&advisory,
`
select
a.id,
a.created_at,
a.year,
a.num,
a.synopsis,
a.topic,
a.severity,
a.type,
a.description,
a.solution,
a.redhat_issued_at,
a.short_code_code,
a.reboot_suggested,
a.published_at,
array_remove(array_agg(distinct p.name), NULL) as affected_products,
(select array_agg(distinct(f.ticket || ':::' || f.source_by || ':::' || f.source_link || ':::' || f.description)) from advisory_fixes adf inner join fixes f on f.id = adf.fix_id where adf.advisory_id = a.id) as fixes,
(select array_agg(distinct(
case when c.content is null then c.source_by || ':::' || c.source_link || ':::' || c.id || ':::::::::'
else c.source_by || ':::' || c.source_link || ':::' || c.id || ':::' || jsonb_extract_path_text(c.content, 'cvss3', 'cvss3_scoring_vector') || ':::' || jsonb_extract_path_text(c.content, 'cvss3', 'cvss3_base_score') || ':::' || jsonb_extract_path_text(c.content, 'cwe')
end
)) from advisory_cves ac inner join cves c on c.id = ac.cve_id where ac.advisory_id = a.id) as cves,
(select array_agg(distinct(url)) from advisory_references where advisory_id = a.id) as references,
(select array_agg(distinct(ar.name || ':::' || p.name)) from advisory_rpms ar inner join products p on p.id = ar.product_id where advisory_id = a.id) as rpms
from advisories a
inner join affected_products ap on ap.advisory = 'RH' || (case when a.type=1 then 'SA' when a.type=2 then 'BA' else 'EA' end) || '-' || a.year || ':' || a.num
inner join products p on ap.product_id = p.id
where
a.year = $1
and a.num = $2
and a.short_code_code = $3
group by a.id
`,
year,
num,
code,
)
if err != nil {
return nil, err
}
return &advisory, nil
}
func (a *Access) CreateAdvisory(advisory *apollodb.Advisory) (*apollodb.Advisory, error) {
var ret apollodb.Advisory
var redHatIssuedAt *time.Time
var publishedAt *time.Time
if advisory.RedHatIssuedAt.Valid {
redHatIssuedAt = &advisory.RedHatIssuedAt.Time
}
if advisory.PublishedAt.Valid {
publishedAt = &advisory.PublishedAt.Time
}
err := a.query.Get(
&ret,
`
insert into advisories
(year, num, synopsis, topic, severity, type, description, solution,
redhat_issued_at, short_code_code, reboot_suggested, published_at)
values ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)
returning
id,
created_at,
year,
num,
synopsis,
topic,
severity,
type,
description,
solution,
redhat_issued_at,
short_code_code,
reboot_suggested,
published_at
`,
advisory.Year,
advisory.Num,
advisory.Synopsis,
advisory.Topic,
advisory.Severity,
advisory.Type,
advisory.Description,
advisory.Solution,
redHatIssuedAt,
advisory.ShortCodeCode,
advisory.RebootSuggested,
publishedAt,
)
if err != nil {
return nil, err
}
return &ret, nil
}
func (a *Access) UpdateAdvisory(advisory *apollodb.Advisory) (*apollodb.Advisory, error) {
var ret apollodb.Advisory
var publishedAt *time.Time
if advisory.PublishedAt.Valid {
publishedAt = &advisory.PublishedAt.Time
}
err := a.query.Get(
&ret,
`
update advisories
set
year = $1,
num = $2,
synopsis = $3,
topic = $4,
severity = $5,
type = $6,
description = $7,
solution = $8,
short_code_code = $9,
reboot_suggested = $10,
published_at = $11
where
id = $12
returning
id,
created_at,
year,
num,
synopsis,
topic,
severity,
type,
description,
solution,
redhat_issued_at,
short_code_code,
reboot_suggested,
published_at
`,
advisory.Year,
advisory.Num,
advisory.Synopsis,
advisory.Topic,
advisory.Severity,
advisory.Type,
advisory.Description,
advisory.Solution,
advisory.ShortCodeCode,
advisory.RebootSuggested,
publishedAt,
advisory.ID,
)
if err != nil {
return nil, err
}
return &ret, nil
}
func (a *Access) GetAllUnresolvedCVEs() ([]*apollodb.CVE, error) {
var cves []*apollodb.CVE
err := a.query.Select(
&cves,
`
select
c.id,
c.created_at,
c.short_code_code,
c.source_by,
c.source_link,
c.content,
ap.id as affected_product_id
from cves c
left join affected_products ap on ap.cve_id = c.id
where (ap.state is null or ap.state in (1, 2, 8, 9))
`,
)
if err != nil {
return nil, err
}
return cves, nil
}
func (a *Access) GetPendingAffectedProducts() ([]*apollodb.AffectedProduct, error) {
var ret []*apollodb.AffectedProduct
err := a.query.Select(
&ret,
`
select
ap.id,
ap.product_id,
ap.cve_id,
ap.state,
ap.version,
ap.package,
ap.advisory
from affected_products ap
where ap.state = 3
`,
)
if err != nil {
return nil, err
}
return ret, nil
}
func (a *Access) GetAllCVEsFixedDownstream() ([]*apollodb.CVE, error) {
var cves []*apollodb.CVE
err := a.query.Select(
&cves,
`
select
c.id,
c.created_at,
c.short_code_code,
c.source_by,
c.source_link,
c.content,
ap.id as affected_product_id
from cves c
inner join affected_products ap on ap.cve_id = c.id
where
ap.state = 4
`,
)
if err != nil {
return nil, err
}
return cves, nil
}
func (a *Access) GetCVEByID(id string) (*apollodb.CVE, error) {
var cve apollodb.CVE
err := a.query.Get(&cve, "select id, created_at, short_code_code, source_by, source_link, content from cves where id = $1", id)
if err != nil {
return nil, err
}
return &cve, nil
}
func (a *Access) GetAllCVEs() ([]*apollodb.CVE, error) {
var cves []*apollodb.CVE
err := a.query.Select(&cves, "select id, created_at, short_code_code, source_by, source_link, content from cves")
if err != nil {
return nil, err
}
return cves, nil
}
func (a *Access) CreateCVE(cveId string, shortCode string, sourceBy *string, sourceLink *string, content types.NullJSONText) (*apollodb.CVE, error) {
var cve apollodb.CVE
err := a.query.Get(&cve, "insert into cves (id, short_code_code, source_by, source_link, content) values ($1, $2, $3, $4, $5) returning id, created_at, short_code_code, source_by, source_link, content", cveId, shortCode, sourceBy, sourceLink, content)
if err != nil {
return nil, err
}
return &cve, nil
}
func (a *Access) SetCVEContent(cveId string, content types.JSONText) error {
_, err := a.query.Exec("update cves set content = $1 where id = $2", content, cveId)
return err
}
func (a *Access) GetProductsByShortCode(code string) ([]*apollodb.Product, error) {
var products []*apollodb.Product
err := a.query.Select(
&products,
`
select
id,
name,
current_full_version,
redhat_major_version,
short_code_code,
archs,
mirror_from_date,
redhat_product_prefix,
cpe,
eol_at,
build_system,
build_system_endpoint,
koji_compose,
koji_module_compose,
peridot_project_id
from products
where
short_code_code = $1
and (eol_at < now() or eol_at is null)
`,
code,
)
if err != nil {
return nil, err
}
return products, nil
}
func (a *Access) GetProductByNameAndShortCode(name string, code string) (*apollodb.Product, error) {
var product apollodb.Product
err := a.query.Get(
&product,
`
select
id,
name,
current_full_version,
redhat_major_version,
short_code_code,
archs,
mirror_from_date,
redhat_product_prefix,
cpe,
eol_at,
build_system,
build_system_endpoint,
koji_compose,
koji_module_compose,
peridot_project_id
from products
where
name = $1
and short_code_code = $2
`,
name,
code,
)
if err != nil {
return nil, err
}
return &product, nil
}
func (a *Access) GetProductByID(id int64) (*apollodb.Product, error) {
var product apollodb.Product
err := a.query.Get(
&product,
`
select
id,
name,
current_full_version,
redhat_major_version,
short_code_code,
archs,
mirror_from_date,
redhat_product_prefix,
cpe,
eol_at,
build_system,
build_system_endpoint,
koji_compose,
koji_module_compose,
peridot_project_id
from products
where
id = $1
`,
id,
)
if err != nil {
return nil, err
}
return &product, nil
}
func (a *Access) CreateProduct(name string, currentFullVersion string, redHatMajorVersion *int32, code string, archs []string) (*apollodb.Product, error) {
var product apollodb.Product
err := a.query.Get(&product, "insert into products (name, current_full_version, redhat_major_version, short_code_code, archs) values ($1, $2, $3, $4) returning id, name, current_full_version, redhat_major_version, short_code_code, archs", name, currentFullVersion, redHatMajorVersion, code, archs)
if err != nil {
return nil, err
}
return &product, nil
}
func (a *Access) GetAllAffectedProductsByCVE(cve string) ([]*apollodb.AffectedProduct, error) {
var affectedProducts []*apollodb.AffectedProduct
err := a.query.Select(&affectedProducts, "select id, product_id, cve_id, state, version, package, advisory from affected_products where cve_id = $1", cve)
if err != nil {
return nil, err
}
return affectedProducts, nil
}
func (a *Access) GetAffectedProductByCVEAndPackage(cve string, pkg string) (*apollodb.AffectedProduct, error) {
var affectedProduct apollodb.AffectedProduct
err := a.query.Get(&affectedProduct, "select id, product_id, cve_id, state, version, package, advisory from affected_products where cve_id = $1 and package = $2", cve, pkg)
if err != nil {
return nil, err
}
return &affectedProduct, nil
}
func (a *Access) GetAffectedProductByAdvisory(advisory string) (*apollodb.AffectedProduct, error) {
var affectedProduct apollodb.AffectedProduct
err := a.query.Get(&affectedProduct, "select id, product_id, cve_id, state, version, package, advisory from affected_products where advisory = $1", advisory)
if err != nil {
return nil, err
}
return &affectedProduct, nil
}
func (a *Access) GetAffectedProductByID(id int64) (*apollodb.AffectedProduct, error) {
var affectedProduct apollodb.AffectedProduct
err := a.query.Get(&affectedProduct, "select id, product_id, cve_id, state, version, package, advisory from affected_products where id = $1", id)
if err != nil {
return nil, err
}
return &affectedProduct, nil
}
func (a *Access) CreateAffectedProduct(productId int64, cveId string, state int, version string, pkg string, advisory *string) (*apollodb.AffectedProduct, error) {
var affectedProduct apollodb.AffectedProduct
err := a.query.Get(&affectedProduct, "insert into affected_products (product_id, cve_id, state, version, package, advisory) values ($1, $2, $3, $4, $5, $6) returning id, product_id, cve_id, state, version, package, advisory", productId, cveId, state, version, pkg, advisory)
if err != nil {
return nil, err
}
return &affectedProduct, nil
}
func (a *Access) UpdateAffectedProductStateAndPackageAndAdvisory(id int64, state int, pkg string, advisory *string) error {
_, err := a.query.Exec(
`
update affected_products
set
state = $1,
package = $2,
advisory = $3
where id = $4
`,
state,
pkg,
advisory,
id,
)
return err
}
func (a *Access) DeleteAffectedProduct(id int64) error {
_, err := a.query.Exec(
`
delete from affected_products
where id = $1
`,
id,
)
return err
}
func (a *Access) CreateFix(ticket string, sourceBy string, sourceLink, description string) (int64, error) {
var id int64
err := a.query.Get(&id, "insert into fixes (ticket, source_by, source_link, description) values ($1, $2, $3, $4) returning id", ticket, sourceBy, sourceLink, description)
return id, err
}
func (a *Access) GetMirrorState(code string) (*apollodb.MirrorState, error) {
var lastSync apollodb.MirrorState
err := a.query.Get(&lastSync, "select short_code_code, last_sync, errata_after from mirror_state where short_code_code = $1", code)
if err != nil {
if err == sql.ErrNoRows {
return nil, nil
}
return nil, err
}
return &lastSync, nil
}
func (a *Access) UpdateMirrorState(code string, lastSync *time.Time) error {
_, err := a.query.Exec(
`
insert into mirror_state (short_code_code, last_sync)
values ($1, $2)
on conflict (short_code_code) do
update
set last_sync = EXCLUDED.last_sync
`,
code,
lastSync,
)
return err
}
func (a *Access) UpdateMirrorStateErrata(code string, lastSync *time.Time) error {
_, err := a.query.Exec(
`
insert into mirror_state (short_code_code, errata_after)
values ($1, $2)
on conflict (short_code_code) do
update
set errata_after = EXCLUDED.errata_after
`,
code,
lastSync,
)
return err
}
func (a *Access) GetMaxLastSync() (*time.Time, error) {
var lastSync time.Time
err := a.query.Get(&lastSync, "select max(last_sync) from mirror_state")
if err != nil {
return nil, err
}
return &lastSync, nil
}
func (a *Access) CreateBuildReference(affectedProductId int64, rpm string, srcRpm string, cveId string, sha256Sum string, kojiId *string, peridotId *string) (*apollodb.BuildReference, error) {
var buildReference apollodb.BuildReference
err := a.query.Get(
&buildReference,
`
insert into build_references
(affected_product_id, rpm, src_rpm, cve_id, sha256_sum, koji_id, peridot_id)
values ($1, $2, $3, $4, $5, $6, $7)
returning id, affected_product_id, rpm, src_rpm, cve_id, sha256_sum, koji_id, peridot_id
`,
affectedProductId,
rpm,
srcRpm,
cveId,
sha256Sum,
kojiId,
peridotId,
)
if err != nil {
return nil, err
}
return &buildReference, nil
}
func (a *Access) CreateAdvisoryReference(advisoryId int64, url string) error {
_, err := a.query.Exec("insert into advisory_references (advisory_id, url) values ($1, $2)", advisoryId, url)
return err
}
func (a *Access) GetAllIgnoredPackagesByProductID(productID int64) ([]string, error) {
var packages []string
err := a.query.Select(&packages, "select package from ignored_upstream_packages where product_id = $1", productID)
if err != nil {
return nil, err
}
return packages, nil
}
func (a *Access) GetAllRebootSuggestedPackages() ([]string, error) {
var packages []string
err := a.query.Select(&packages, "select name from reboot_suggested_packages")
if err != nil {
return nil, err
}
return packages, nil
}
func (a *Access) AddAdvisoryFix(advisoryId int64, fixId int64) error {
_, err := a.query.Exec("insert into advisory_fixes (advisory_id, fix_id) values ($1, $2) on conflict do nothing", advisoryId, fixId)
if err != nil {
return err
}
return nil
}
func (a *Access) AddAdvisoryCVE(advisoryId int64, cveId string) error {
_, err := a.query.Exec("insert into advisory_cves (advisory_id, cve_id) values ($1, $2) on conflict do nothing", advisoryId, cveId)
if err != nil {
return err
}
return nil
}
func (a *Access) AddAdvisoryRPM(advisoryId int64, name string, productID int64) error {
_, err := a.query.Exec("insert into advisory_rpms (advisory_id, name, product_id) values ($1, $2, $3) on conflict do nothing", advisoryId, name, productID)
if err != nil {
return err
}
return nil
}
func (a *Access) Begin() (utils.Tx, error) {
tx, err := a.db.Beginx()
if err != nil {
return nil, err
}
return tx, nil
}
func (a *Access) UseTransaction(tx utils.Tx) apollodb.Access {
newAccess := *a
newAccess.query = tx
return &newAccess
}

View File

@ -6,16 +6,21 @@ go_library(
"advisory.go",
"server.go",
],
importpath = "peridot.resf.org/secparse/impl",
importpath = "peridot.resf.org/apollo/impl/v1",
visibility = ["//visibility:public"],
deps = [
"//secparse/db",
"//secparse/proto/v1:proto",
"//secparse/rpmutils",
"//apollo/db",
"//apollo/proto/v1:pb",
"//apollo/rpmutils",
"//proto:common",
"//utils",
"//vendor/github.com/gorilla/feeds",
"//vendor/github.com/sirupsen/logrus",
"//vendor/github.com/spf13/viper",
"@go_googleapis//google/api:httpbody_go_proto",
"@org_golang_google_grpc//:go_default_library",
"@org_golang_google_grpc//codes",
"@org_golang_google_grpc//status",
"@org_golang_google_protobuf//types/known/timestamppb:go_default_library",
],
)

182
apollo/impl/v1/advisory.go Normal file
View File

@ -0,0 +1,182 @@
// 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.
package apolloimpl
import (
"context"
"database/sql"
"fmt"
"github.com/gorilla/feeds"
"github.com/sirupsen/logrus"
"google.golang.org/genproto/googleapis/api/httpbody"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/types/known/timestamppb"
apollodb "peridot.resf.org/apollo/db"
apollopb "peridot.resf.org/apollo/pb"
"peridot.resf.org/apollo/rpmutils"
"peridot.resf.org/utils"
"strconv"
"time"
)
func (s *Server) ListAdvisories(_ context.Context, req *apollopb.ListAdvisoriesRequest) (*apollopb.ListAdvisoriesResponse, error) {
if err := req.ValidateAll(); err != nil {
return nil, err
}
if req.Filters != nil {
req.Filters.IncludeUnpublished = nil
}
page := utils.MinPage(req.Page)
limit := utils.MinLimit(req.Limit)
ret, err := s.db.GetAllAdvisories(req.Filters, page, limit)
if err != nil {
s.log.Errorf("could not get advisories, error: %s", err)
return nil, status.Error(codes.Internal, "failed to list advisories")
}
total := int64(0)
if len(ret) > 0 {
total = ret[0].Total
}
var lastUpdatedPb *timestamppb.Timestamp
lastUpdated, err := s.db.GetMaxLastSync()
if err != nil && err != sql.ErrNoRows {
s.log.Errorf("could not get last sync time, error: %s", err)
return nil, status.Error(codes.Internal, "failed to get last updated")
}
if lastUpdated != nil {
lastUpdatedPb = timestamppb.New(*lastUpdated)
}
return &apollopb.ListAdvisoriesResponse{
Advisories: apollodb.DTOListAdvisoriesToPB(ret),
Total: total,
Page: page,
Size: limit,
LastUpdated: lastUpdatedPb,
}, nil
}
func (s *Server) ListAdvisoriesRSS(_ context.Context, req *apollopb.ListAdvisoriesRSSRequest) (*httpbody.HttpBody, error) {
if err := req.ValidateAll(); err != nil {
return nil, err
}
if req.Filters == nil {
req.Filters = &apollopb.AdvisoryFilters{}
}
req.Filters.IncludeUnpublished = nil
ret, err := s.db.GetAllAdvisories(req.Filters, 0, 25)
if err != nil {
s.log.Errorf("could not get advisories, error: %s", err)
return nil, status.Error(codes.Internal, "failed to list advisories")
}
total := int64(0)
if len(ret) > 0 {
total = ret[0].Total
}
var updated time.Time
if total != 0 {
updated = ret[0].PublishedAt.Time
}
feed := &feeds.Feed{
Title: "Apollo Security RSS Feed",
Link: &feeds.Link{Href: s.homepage},
Description: "Security advisories issued using Apollo Errata Management",
Author: &feeds.Author{
Name: "Rocky Enterprise Software Foundation, Inc.",
Email: "releng@rockylinux.org",
},
Updated: updated,
Items: []*feeds.Item{},
Copyright: "(C) Rocky Enterprise Software Foundation, Inc. 2022. All rights reserved. CVE sources are copyright of their respective owners.",
}
if s.rssFeedTitle != "" {
feed.Title = s.rssFeedTitle
}
if s.rssFeedDescription != "" {
feed.Description = s.rssFeedDescription
}
for _, a := range ret {
dtoToPB := apollodb.DTOAdvisoryToPB(a)
item := &feeds.Item{
Title: fmt.Sprintf("%s: %s", dtoToPB.Name, a.Synopsis),
Link: &feeds.Link{Href: fmt.Sprintf("%s/%s", s.homepage, dtoToPB.Name)},
Description: a.Topic,
Id: fmt.Sprintf("%d", a.ID),
Created: a.PublishedAt.Time,
}
feed.Items = append(feed.Items, item)
}
rss, err := feed.ToRss()
if err != nil {
s.log.Errorf("could not generate RSS feed, error: %s", err)
return nil, status.Error(codes.Internal, "failed to generate RSS feed")
}
return &httpbody.HttpBody{
ContentType: "application/rss+xml",
Data: []byte(rss),
}, nil
}
func (s *Server) GetAdvisory(_ context.Context, req *apollopb.GetAdvisoryRequest) (*apollopb.GetAdvisoryResponse, error) {
if err := req.ValidateAll(); err != nil {
return nil, err
}
advisoryId := rpmutils.AdvisoryId().FindStringSubmatch(req.Id)
code := advisoryId[1]
year, err := strconv.Atoi(advisoryId[3])
if err != nil {
return nil, status.Error(codes.InvalidArgument, "invalid year")
}
num, err := strconv.Atoi(advisoryId[4])
if err != nil {
return nil, status.Error(codes.InvalidArgument, "invalid num")
}
advisory, err := s.db.GetAdvisoryByCodeAndYearAndNum(code, year, num)
if err != nil {
logrus.Error(err)
}
if err != nil || !advisory.PublishedAt.Valid {
return nil, utils.CouldNotFindObject
}
return &apollopb.GetAdvisoryResponse{
Advisory: apollodb.DTOAdvisoryToPB(advisory),
}, nil
}

View File

@ -28,50 +28,41 @@
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package impl
package apolloimpl
import (
"context"
hydraclient "github.com/ory/hydra-client-go/client"
"github.com/sirupsen/logrus"
"github.com/spf13/viper"
"google.golang.org/grpc"
"net/url"
secparseadminpb "peridot.resf.org/secparse/admin/proto/v1"
"peridot.resf.org/secparse/db"
"peridot.resf.org/servicecatalog"
apollodb "peridot.resf.org/apollo/db"
apollopb "peridot.resf.org/apollo/pb"
commonpb "peridot.resf.org/common"
"peridot.resf.org/utils"
)
type Server struct {
secparseadminpb.UnimplementedSecparseAdminServer
apollopb.UnimplementedApolloServiceServer
log *logrus.Logger
db db.Access
hydra *hydraclient.OryHydra
log *logrus.Logger
db apollodb.Access
rssFeedTitle string
rssFeedDescription string
homepage string
}
func NewServer(db db.Access) *Server {
publicURL, err := url.Parse(servicecatalog.HydraPublic())
if err != nil {
logrus.Fatalf("failed to parse hydra public url: %s", err)
}
hydraSDK := hydraclient.NewHTTPClientWithConfig(nil, &hydraclient.TransportConfig{
Schemes: []string{publicURL.Scheme},
Host: publicURL.Host,
BasePath: publicURL.Path,
})
func NewServer(db apollodb.Access) *Server {
return &Server{
log: logrus.New(),
db: db,
hydra: hydraSDK,
log: logrus.New(),
db: db,
rssFeedTitle: "RESF Errata Feed",
rssFeedDescription: "Advisories issued by the Rocky Enterprise Software Foundation",
homepage: viper.GetString("homepage"),
}
}
func (s *Server) interceptor(ctx context.Context, req interface{}, usi *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
n := utils.EndInterceptor
n = utils.AuthInterceptor(s.hydra, nil, []string{}, true, n)
return n(ctx, req, usi, handler)
}
@ -82,18 +73,22 @@ func (s *Server) Run() {
Interceptor: s.interceptor,
},
func(r *utils.Register) {
err := secparseadminpb.RegisterSecparseAdminHandlerFromEndpoint(
r.Context,
r.Mux,
r.Endpoint,
r.Options,
)
if err != nil {
s.log.Fatalf("could not register handler - %s", err)
endpoints := []utils.GrpcEndpointRegister{
commonpb.RegisterHealthCheckServiceHandlerFromEndpoint,
apollopb.RegisterApolloServiceHandlerFromEndpoint,
}
for _, endpoint := range endpoints {
err := endpoint(r.Context, r.Mux, r.Endpoint, r.Options)
if err != nil {
s.log.Fatalf("could not register handler - %v", err)
}
}
},
func(r *utils.RegisterServer) {
secparseadminpb.RegisterSecparseAdminServer(r.Server, s)
commonpb.RegisterHealthCheckServiceServer(r.Server, &utils.HealthServer{})
apollopb.RegisterApolloServiceServer(r.Server, s)
},
)

View File

@ -34,8 +34,6 @@ create table short_codes
(
code text not null primary key,
mode numeric not null,
mirror_from_date timestamp,
redhat_product_prefix text,
created_at timestamp default now() not null,
archived_at timestamp

View File

@ -32,11 +32,20 @@
create table products
(
id bigserial primary key,
name text not null,
current_full_version text not null,
redhat_major_version numeric,
short_code_code text references short_codes (code) not null,
archs text[] not null,
eol_at timestamp
id bigserial primary key,
name text not null,
current_full_version text not null,
redhat_major_version numeric,
short_code_code text references short_codes (code) not null,
archs text[] not null,
mirror_from_date timestamp,
redhat_product_prefix text,
cpe text,
eol_at timestamp,
build_system text not null,
build_system_endpoint text not null,
koji_compose text,
koji_module_compose text,
peridot_project_id text
)

View File

@ -32,20 +32,21 @@
create table advisories
(
id bigserial primary key not null,
created_at timestamp default now() not null,
id bigserial primary key not null,
created_at timestamp default now() not null,
year numeric not null,
num numeric not null,
year numeric not null,
num numeric not null,
synopsis text not null,
topic text not null,
severity numeric not null,
type numeric not null,
description text not null,
solution text null,
synopsis text not null,
topic text not null,
severity numeric not null,
type numeric not null,
description text not null,
solution text null,
redhat_issued_at timestamp null,
short_code_code text references short_codes (code) not null,
published_at timestamp null
redhat_issued_at timestamp null,
short_code_code text references short_codes (code) not null,
reboot_suggested bool default false not null,
published_at timestamp null
)

View File

@ -34,7 +34,6 @@ create table cves
(
id text primary key,
created_at timestamp default now() not null,
state numeric not null,
short_code_code text references short_codes (code) not null,
source_by text,

View File

@ -32,7 +32,9 @@
create table fixes
(
id bigserial primary key,
ticket text,
description text
id bigserial primary key,
ticket text,
source_by text,
source_link text,
description text
)

View File

@ -32,11 +32,12 @@
create table build_references
(
id bigserial primary key,
affected_product_id bigint references affected_products (id),
rpm text not null,
src_rpm text not null,
cve_id text references cves (id) not null,
koji_id text,
peridot_id text
id bigserial primary key,
affected_product_id bigint references affected_products (id),
rpm text not null,
src_rpm text not null,
cve_id text references cves (id) not null,
sha256_sum text not null,
koji_id text,
peridot_id text
)

View File

@ -32,6 +32,7 @@
create table mirror_state
(
short_code_code text references short_codes (code) primary key,
last_sync timestamp
short_code_code text references short_codes (code) primary key,
last_sync timestamp,
errata_after timestamp
);

View File

@ -32,7 +32,7 @@
create table ignored_upstream_packages
(
id bigserial primary key,
short_code_code text references short_codes (code) not null,
package text not null
id bigserial primary key,
product_id bigint references products (id) not null,
package text not null
);

View File

@ -32,8 +32,9 @@
create table advisory_rpms
(
advisory_id bigint references advisories (id) not null,
name text not null,
advisory_id bigint references advisories (id) not null,
name text not null,
product_id bigint references products (id) not null,
unique (advisory_id, name)
unique (advisory_id, name)
)

View File

@ -0,0 +1 @@
drop table reboot_suggested_packages;

View File

@ -0,0 +1,6 @@
create table reboot_suggested_packages
(
created_at timestamp default now() not null,
name text unique not null
)

View File

@ -0,0 +1,9 @@
drop index affected_products_advisoryx;
drop index affected_products_product_idx;
drop index advisory_fixes_advisory_idx;
drop index advisory_fixes_fix_idx;
drop index advisory_cves_advisory_idx;
drop index advisory_cves_cve_idx;
drop index advisory_references_advisory_idx;
drop index advisory_rpms_advisory_idx;
drop index advisory_rpms_product_idx;

View File

@ -0,0 +1,9 @@
create index affected_products_advisoryx on affected_products (advisory);
create index affected_products_product_idx on affected_products (product_id);
create index advisory_fixes_advisory_idx on advisory_fixes (advisory_id);
create index advisory_fixes_fix_idx on advisory_fixes (fix_id);
create index advisory_cves_advisory_idx on advisory_cves (advisory_id);
create index advisory_cves_cve_idx on advisory_cves (cve_id);
create index advisory_references_advisory_idx on advisory_references (advisory_id);
create index advisory_rpms_advisory_idx on advisory_rpms (advisory_id);
create index advisory_rpms_product_idx on advisory_rpms (product_id);

View File

@ -0,0 +1 @@
alter table cves drop column content;

View File

@ -0,0 +1 @@
alter table cves add column content jsonb;

View File

@ -1,48 +1,58 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
load("@rules_proto//proto:defs.bzl", "proto_library")
load("@io_bazel_rules_go//go:def.bzl", "go_library")
load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
load("@com_github_grpc_ecosystem_grpc_gateway_v2//protoc-gen-openapiv2:defs.bzl", "protoc_gen_openapiv2")
load("@openapi_tools_generator_bazel//:defs.bzl", "openapi_generator")
proto_library(
name = "secparsepb_proto",
name = "apollopb_proto",
srcs = [
"advisory.proto",
"secparse.proto",
"affected_product.proto",
"apollo.proto",
"build.proto",
"cve.proto",
"fix.proto",
"short_code.proto",
],
visibility = ["//visibility:public"],
deps = [
"//proto:commonpb_proto",
"@com_envoyproxy_protoc_gen_validate//validate:validate_proto",
"@com_github_grpc_ecosystem_grpc_gateway_v2//protoc-gen-openapiv2/options:options_proto",
"@com_google_protobuf//:timestamp_proto",
"@com_google_protobuf//:wrappers_proto",
"@go_googleapis//google/api:annotations_proto",
"@go_googleapis//google/api:httpbody_proto",
],
)
go_proto_library(
name = "secparsepb_go_proto",
name = "apollopb_go_proto",
compilers = [
"//:go_apiv2",
"//:go_grpc",
"//:go_validate",
"@com_github_grpc_ecosystem_grpc_gateway_v2//protoc-gen-grpc-gateway:go_gen_grpc_gateway",
],
importpath = "peridot.resf.org/secparse/proto/v1",
proto = ":secparsepb_proto",
importpath = "peridot.resf.org/apollo/pb",
proto = ":apollopb_proto",
visibility = ["//visibility:public"],
deps = [
"//proto:common",
"@com_envoyproxy_protoc_gen_validate//validate:validate_go_proto",
"@com_github_grpc_ecosystem_grpc_gateway_v2//protoc-gen-openapiv2/options:options_go_proto",
"@go_googleapis//google/api:annotations_go_proto",
"@go_googleapis//google/api:httpbody_go_proto",
],
)
go_library(
name = "pb",
embed = [":apollopb_go_proto"],
importpath = "peridot.resf.org/apollo/pb",
visibility = ["//visibility:public"],
)
protoc_gen_openapiv2(
name = "openapi",
proto = ":secparsepb_proto",
proto = ":apollopb_proto",
simple_operation_ids = True,
single_output = True,
)
@ -53,10 +63,3 @@ openapi_generator(
spec = ":openapi",
visibility = ["//visibility:public"],
)
go_library(
name = "proto",
embed = [":secparsepb_go_proto"],
importpath = "peridot.resf.org/secparse/proto/v1",
visibility = ["//visibility:public"],
)

View File

@ -1,22 +1,27 @@
syntax = "proto3";
package resf.secparse;
package resf.apollo.v1;
import "google/protobuf/timestamp.proto";
import "google/protobuf/wrappers.proto";
import "validate/validate.proto";
import "apollo/proto/v1/cve.proto";
import "apollo/proto/v1/fix.proto";
option go_package = "peridot.resf.org/secparse/proto/v1;secparsepb";
option go_package = "peridot.resf.org/apollo/pb;apollopb";
message RPMs {
repeated string nvras = 1;
}
// Advisory
//
// Product advisory
message Advisory {
enum Type {
UnknownType = 0;
Security = 1;
BugFix = 2;
Enhancement = 3;
TYPE_UNKNOWN = 0;
TYPE_SECURITY = 1;
TYPE_BUGFIX = 2;
TYPE_ENHANCEMENT = 3;
}
// Type
@ -42,11 +47,11 @@ message Advisory {
string synopsis = 4;
enum Severity {
UnknownSeverity = 0;
Low = 1;
Moderate = 2;
Important = 3;
Critical = 4;
SEVERITY_UNKNOWN = 0;
SEVERITY_LOW = 1;
SEVERITY_MODERATE = 2;
SEVERITY_IMPORTANT = 3;
SEVERITY_CRITICAL = 4;
}
// Severity
@ -78,12 +83,12 @@ message Advisory {
// Fixes
//
// A list of tickets from upstream bug trackers
repeated string fixes = 10;
repeated Fix fixes = 10;
// CVEs
//
// A list of CVEs assigned to this advisory
repeated string cves = 11;
repeated CVE cves = 11;
// References
//
@ -98,60 +103,10 @@ message Advisory {
// RPMs
//
// Affected RPMs
repeated string rpms = 14;
}
map<string, RPMs> rpms = 14;
// ListAdvisoriesRequest
//
// Request body for `ListAdvisories`
// All fields are optional
message ListAdvisoriesRequest {
// Product
// Reboot suggested
//
// The product to fetch advisories for
// For example: Rocky Linux, RL or Rocky
string product = 1;
// Version
//
// The version to fetch advisories for
// For example: 8.3 or 8.4
string version = 2;
// Before
//
// Advisories published before timestamp
google.protobuf.Timestamp before = 3;
// After
//
// Advisories published after timestamp
google.protobuf.Timestamp after = 4;
}
// ListAdvisoriesResponse
//
// Response body for `ListAdvisories`
message ListAdvisoriesResponse {
repeated Advisory advisories = 1;
}
// GetAdvisoryRequest
//
// Request body for `GetAdvisory`
message GetAdvisoryRequest {
// ID
//
// Errata ID
// Example: RLSA:2021-1515
string id = 1 [(validate.rules).string = {
pattern: "^(.+)([SEB]A)-([0-9]{4}):([0-9]+)$",
}];
}
// GetAdvisoryResponse
//
// Response body for `GetAdvisory`
message GetAdvisoryResponse {
Advisory advisory = 1;
// Whether a system reboot should be suggested after applying this advisory
bool reboot_suggested = 15;
}

View File

@ -0,0 +1,41 @@
syntax = "proto3";
package resf.apollo.v1;
import "google/protobuf/wrappers.proto";
option go_package = "peridot.resf.org/apollo/pb;apollopb";
message AffectedProduct {
int64 product_id = 1;
google.protobuf.StringValue cve_id = 2;
string version = 3;
enum State {
STATE_UNKNOWN = 0;
// CVE only affects downstream
STATE_UNDER_INVESTIGATION_DOWNSTREAM = 1;
// CVE affecting upstream and a fix still hasn't been issued
STATE_UNDER_INVESTIGATION_UPSTREAM = 2;
// CVE has been fixed upstream
STATE_FIXED_UPSTREAM = 3;
// CVE has been fixed downstream
// At this stage the CVE can be included in errata
STATE_FIXED_DOWNSTREAM = 4;
// CVE will NOT be fixed upstream
STATE_WILL_NOT_FIX_UPSTREAM = 5;
// CVE will NOT be fixed downstream
// This will probably never happen with Core, but may happen for SIGs
STATE_WILL_NOT_FIX_DOWNSTREAM = 6;
// CVE is out of support scope
STATE_OUT_OF_SUPPORT_SCOPE = 7;
// CVE affects product and upstream is working on a fix
STATE_AFFECTED_UPSTREAM = 8;
// CVE affects product and a fix is being worked out
STATE_AFFECTED_DOWNSTREAM = 9;
}
State state = 4;
string package = 5;
google.protobuf.StringValue advisory = 6;
}

View File

@ -0,0 +1,161 @@
syntax = "proto3";
package resf.apollo.v1;
import "google/api/annotations.proto";
import "google/api/httpbody.proto";
import "google/protobuf/wrappers.proto";
import "google/protobuf/timestamp.proto";
import "validate/validate.proto";
import "apollo/proto/v1/advisory.proto";
option go_package = "peridot.resf.org/apollo/pb;apollopb";
service ApolloService {
// ListAdvisories
//
// Return a list of advisories by given filters.
// No filters returns all advisories
// This method is paginated
rpc ListAdvisories (ListAdvisoriesRequest) returns (ListAdvisoriesResponse) {
option (google.api.http) = {
get: "/v2/advisories"
};
}
// ListAdvisoriesRSS
//
// Same as ListAdvisories but returns an RSS feed
// Only returns 25 latest advisories
// Supports filters
rpc ListAdvisoriesRSS (ListAdvisoriesRSSRequest) returns (google.api.HttpBody) {
option (google.api.http) = {
get: "/v2/advisories:rss"
};
}
// GetAdvisory
//
// Returns an advisory with given ID if found, else returns NotFound
rpc GetAdvisory (GetAdvisoryRequest) returns (GetAdvisoryResponse) {
option (google.api.http) = {
get: "/v2/advisories/{id=*}"
};
}
}
message AdvisoryFilters {
// Product
//
// The product to fetch advisories for
// For example: Rocky Linux 8
google.protobuf.StringValue product = 1;
// Before
//
// Advisories published before timestamp
google.protobuf.Timestamp before = 2;
// After
//
// Advisories published after timestamp
google.protobuf.Timestamp after = 3;
// Include unpublished
//
// Whether to include unpublished advisories
// apollo/impl never respects this, but internal services
// may rely on this
google.protobuf.BoolValue include_unpublished = 4;
// CVE
//
// Only return advisories with given CVE
google.protobuf.StringValue cve = 5;
// Synopsis
//
// Only return advisories if synopsis contains given text
google.protobuf.StringValue synopsis = 6;
// Include RPMs
//
// Includes RPMs in list response (slow)
google.protobuf.BoolValue include_rpms = 7;
// Keyword
//
// Searches all fields for given keyword
google.protobuf.StringValue keyword = 8;
// Severity
//
// Only return advisories with given severity
Advisory.Severity severity = 9;
// Type
//
// Only return advisories with given type
Advisory.Type type = 10;
}
// ListAdvisoriesRequest
//
// Request body for `ListAdvisories`
// All fields are optional
message ListAdvisoriesRequest {
// Filters for the given query
// No filters returns all advisories
AdvisoryFilters filters = 1;
int32 page = 2;
int32 limit = 3 [(validate.rules).int32.lte = 100];
}
// ListAdvisoriesResponse
//
// Response body for `ListAdvisories`
message ListAdvisoriesResponse {
repeated Advisory advisories = 1;
// Total packages from server
int64 total = 2;
// Limit from request
int32 size = 3;
// Current page
int32 page = 4;
// Last updated
google.protobuf.Timestamp last_updated = 5;
}
// ListAdvisoriesRSSRequest
// Request body for `ListAdvisoriesRSS`
// All fields are optional
message ListAdvisoriesRSSRequest {
// Filters for the given query
// No filters returns all advisories
AdvisoryFilters filters = 1;
}
// GetAdvisoryRequest
//
// Request body for `GetAdvisory`
message GetAdvisoryRequest {
// ID
//
// Errata ID
// Example: RLSA:2021-1515
string id = 1 [(validate.rules).string = {
pattern: "^(.+)([SEB]A)-([0-9]{4}):([0-9]+)$",
}];
}
// GetAdvisoryResponse
//
// Response body for `GetAdvisory`
message GetAdvisoryResponse {
Advisory advisory = 1;
}

View File

@ -0,0 +1,13 @@
syntax = "proto3";
package resf.apollo.v1;
option go_package = "peridot.resf.org/apollo/pb;apollopb";
enum BuildStatus {
BUILD_STATUS_UNKNOWN = 0;
BUILD_STATUS_FIXED = 1;
BUILD_STATUS_NOT_FIXED = 2;
BUILD_STATUS_WILL_NOT_FIX = 3;
BUILD_STATUS_SKIP = 4;
}

28
apollo/proto/v1/cve.proto Normal file
View File

@ -0,0 +1,28 @@
syntax = "proto3";
package resf.apollo.v1;
import "google/protobuf/wrappers.proto";
option go_package = "peridot.resf.org/apollo/pb;apollopb";
message CVE {
string name = 1;
google.protobuf.StringValue source_by = 2;
google.protobuf.StringValue source_link = 3;
google.protobuf.StringValue cvss3_scoring_vector = 4;
google.protobuf.StringValue cvss3_base_score = 5;
google.protobuf.StringValue cwe = 6;
}
message ListUnresolvedCVEsRequest {}
message ListUnresolvedCVEsResponse {
repeated CVE cves = 1;
}
message ListFixedCVEsRequest {}
message ListFixedCVEsResponse {
repeated CVE cves = 1;
}

14
apollo/proto/v1/fix.proto Normal file
View File

@ -0,0 +1,14 @@
syntax = "proto3";
package resf.apollo.v1;
import "google/protobuf/wrappers.proto";
option go_package = "peridot.resf.org/apollo/pb;apollopb";
message Fix {
google.protobuf.StringValue ticket = 1;
google.protobuf.StringValue source_by = 2;
google.protobuf.StringValue source_link = 3;
google.protobuf.StringValue description = 4;
}

View File

@ -0,0 +1,29 @@
syntax = "proto3";
package resf.apollo.v1;
option go_package = "peridot.resf.org/apollo/pb;apollopb";
message ShortCode {
// Code
//
// Full short code
string code = 1;
enum Mode {
MODE_UNKNOWN = 0;
MODE_PUBLISH = 1;
MODE_MIRROR = 2;
}
// Mode
//
// Mode for short code
// Currently only publish and mirror is supported
Mode mode = 2;
// Archived
//
// Whether the short code is archived or not
// An archived short code CANNOT be used to issue errata
bool archived = 3;
}

View File

@ -8,10 +8,10 @@ go_library(
"errata.go",
"mock.go",
],
importpath = "peridot.resf.org/secparse/rherrata",
importpath = "peridot.resf.org/apollo/rherrata",
visibility = ["//visibility:public"],
deps = [
"//secparse/proto/v1:proto",
"//apollo/proto/v1:pb",
"//vendor/github.com/PuerkitoBio/goquery",
"//vendor/github.com/go-chi/chi",
"//vendor/github.com/gocolly/colly/v2:colly",
@ -24,7 +24,7 @@ go_test(
data = glob(["testdata/**"]),
embed = [":rherrata"],
deps = [
"//secparse/proto/v1:proto",
"//apollo/proto/v1:pb",
"//vendor/github.com/stretchr/testify/require",
],
)

View File

@ -38,7 +38,7 @@ import (
type APIService interface {
GetErrata(advisory string) (*Errata, error)
GetAdvisories(currentVersion string) ([]*CompactErrata, error)
GetAdvisories(currentVersion string, after *time.Time) ([]*CompactErrata, error)
}
// API is the APIService implementation. Should not be used directly
@ -54,9 +54,9 @@ func NewClient() *API {
client: &http.Client{
Timeout: 30 * time.Second,
},
userAgent: "secparse/rherrata/0.1",
userAgent: "apollo/rherrata/0.2",
baseURLErrata: "https://access.redhat.com/errata",
baseURLAPI: "https://api.access.redhat.com/rs/search",
baseURLAPI: "https://access.redhat.com/hydra/rest/search/kcs",
}
}

View File

@ -35,10 +35,12 @@ import (
"fmt"
"net/url"
"strings"
"time"
)
var internalAfterDates = map[string]string{
"8.4": "2021-04-29T00:00:00Z",
"9.0": "2022-05-17T00:00:00Z",
}
type CompactErrata struct {
@ -61,7 +63,7 @@ type internalAdvisoriesResponse struct {
Response *internalAdvisoriesInnerResponse `json:"response"`
}
func (a *API) GetAdvisories(currentVersion string) ([]*CompactErrata, error) {
func (a *API) GetAdvisories(currentVersion string, after *time.Time) ([]*CompactErrata, error) {
req, err := a.newRequest("GET", a.baseURLAPI, nil)
if err != nil {
return nil, err
@ -71,12 +73,14 @@ func (a *API) GetAdvisories(currentVersion string) ([]*CompactErrata, error) {
usableVersion := strings.Replace(currentVersion, ".", "%5C.", -1)
fq2 := fmt.Sprintf("portal_product_filter:Red%%5C+Hat%%5C+Enterprise%%5C+Linux%%7C*%%7C%s%%7C*", usableVersion)
var fq3 string
if afterDate := internalAfterDates[currentVersion]; afterDate != "" {
if after != nil {
fq3 = "&fq=" + url.QueryEscape(fmt.Sprintf("portal_publication_date:[%s TO NOW]", after.Format(time.RFC3339)))
} else if afterDate := internalAfterDates[currentVersion]; afterDate != "" {
fq3 = "&fq=" + url.QueryEscape(fmt.Sprintf("portal_publication_date:[%s TO NOW]", afterDate))
}
req.URL.RawQuery = fmt.Sprintf("fq=%s&fq=%s%s&q=*:*&rows=1000&sort=portal_publication_date+desc&start=0", fq1, fq2, fq3)
req.URL.RawQuery = fmt.Sprintf("fq=%s&fq=%s%s&q=*:*&rows=10000&sort=portal_publication_date+desc&start=0", fq1, fq2, fq3)
req.Header.Set("Accept", "application/vnd.redhat.solr+json")
req.Header.Set("Accept", "application/json")
res, err := a.client.Do(req)
if err != nil {

View File

@ -35,7 +35,7 @@ import (
"fmt"
"github.com/PuerkitoBio/goquery"
"github.com/gocolly/colly/v2"
secparsepb "peridot.resf.org/secparse/proto/v1"
apollopb "peridot.resf.org/apollo/pb"
"strings"
"time"
)
@ -62,8 +62,8 @@ type UpdatedPackages struct {
type Errata struct {
Synopsis string
Type secparsepb.Advisory_Type
Severity secparsepb.Advisory_Severity
Type apollopb.Advisory_Type
Severity apollopb.Advisory_Severity
Topic []string
Description []string
Solution []string
@ -178,9 +178,9 @@ func (a *API) GetErrata(advisory string) (*Errata, error) {
c.OnHTML("div#type-severity", func(element *colly.HTMLElement) {
typeSeverity := strings.Split(element.DOM.Find("p").Text(), ":")
if typeSeverity[0] == "Product Enhancement Advisory" {
errata.Type = secparsepb.Advisory_Enhancement
errata.Type = apollopb.Advisory_TYPE_ENHANCEMENT
} else if typeSeverity[0] == "Bug Fix Advisory" {
errata.Type = secparsepb.Advisory_BugFix
errata.Type = apollopb.Advisory_TYPE_BUGFIX
} else {
if len(typeSeverity) != 2 {
err = errors.New("invalid type/severity")
@ -195,28 +195,28 @@ func (a *API) GetErrata(advisory string) (*Errata, error) {
switch strings.TrimSpace(typeSplit[0]) {
case "Security":
errata.Type = secparsepb.Advisory_Security
errata.Type = apollopb.Advisory_TYPE_SECURITY
break
case "BugFix":
errata.Type = secparsepb.Advisory_BugFix
errata.Type = apollopb.Advisory_TYPE_BUGFIX
break
case "Enhancement":
errata.Type = secparsepb.Advisory_Enhancement
errata.Type = apollopb.Advisory_TYPE_ENHANCEMENT
break
}
switch strings.TrimSpace(typeSeverity[1]) {
case "Low":
errata.Severity = secparsepb.Advisory_Low
errata.Severity = apollopb.Advisory_SEVERITY_LOW
break
case "Moderate":
errata.Severity = secparsepb.Advisory_Moderate
errata.Severity = apollopb.Advisory_SEVERITY_MODERATE
break
case "Important":
errata.Severity = secparsepb.Advisory_Important
errata.Severity = apollopb.Advisory_SEVERITY_IMPORTANT
break
case "Critical":
errata.Severity = secparsepb.Advisory_Critical
errata.Severity = apollopb.Advisory_SEVERITY_CRITICAL
break
}
}

View File

@ -33,7 +33,7 @@ package rherrata
import (
"github.com/stretchr/testify/require"
"io/ioutil"
secparsepb "peridot.resf.org/secparse/proto/v1"
apollopb "peridot.resf.org/apollo/pb"
"testing"
)
@ -53,7 +53,7 @@ func TestRHBA20212759(t *testing.T) {
require.Nil(t, err)
require.Equal(t, "firefox bugfix update", errata.Synopsis)
require.Equal(t, secparsepb.Advisory_BugFix, errata.Type)
require.Equal(t, apollopb.Advisory_TYPE_BUGFIX, errata.Type)
require.Len(t, errata.Topic, 1)
require.Equal(t, "An update for firefox is now available for Red Hat Enterprise Linux 8.", errata.Topic[0])
require.Len(t, errata.Description, 3)
@ -95,8 +95,8 @@ func TestRHBA20212743(t *testing.T) {
require.Nil(t, err)
require.Equal(t, "Important: firefox security update", errata.Synopsis)
require.Equal(t, secparsepb.Advisory_Security, errata.Type)
require.Equal(t, secparsepb.Advisory_Important, errata.Severity)
require.Equal(t, apollopb.Advisory_TYPE_SECURITY, errata.Type)
require.Equal(t, apollopb.Advisory_SEVERITY_IMPORTANT, errata.Severity)
require.Len(t, errata.Topic, 2)
require.Equal(t, "An update for firefox is now available for Red Hat Enterprise Linux 8.", errata.Topic[0])
require.Equal(t, "Red Hat Product Security has rated this update as having a security impact of Important. A Common Vulnerability Scoring System (CVSS) base score, which gives a detailed severity rating, is available for each vulnerability from the CVE link(s) in the References section.", errata.Topic[1])

View File

@ -16,7 +16,7 @@ go_library(
"response.go",
"utils.go",
],
importpath = "peridot.resf.org/secparse/rhsecurity",
importpath = "peridot.resf.org/apollo/rhsecurity",
visibility = ["//visibility:public"],
deps = ["//vendor/golang.org/x/oauth2"],
)

View File

@ -1,4 +1,6 @@
openapi: 3.0.0
x-stoplight:
id: yjn90w5p8y4ly
info:
title: Red Hat Security Data API
version: '1.0'
@ -63,7 +65,7 @@ paths:
name: cwe
description: CVEs with CWE
- schema:
type: string
type: number
in: query
name: cvss_score
description: CVEs with CVSS score greater than or equal to this value
@ -181,7 +183,7 @@ components:
type: string
minLength: 1
cvss_score:
type: string
type: number
cvss_scoring_vector:
type: string
CWE:

View File

@ -61,12 +61,11 @@ type DefaultApi interface {
type DefaultApiService service
type ApiGetCveRequest struct {
ctx _context.Context
ctx _context.Context
ApiService DefaultApi
cVE string
cVE string
}
func (r ApiGetCveRequest) Execute() (CVEDetailed, *_nethttp.Response, error) {
return r.ApiService.GetCveExecute(r)
}
@ -81,8 +80,8 @@ func (r ApiGetCveRequest) Execute() (CVEDetailed, *_nethttp.Response, error) {
func (a *DefaultApiService) GetCve(ctx _context.Context, cVE string) ApiGetCveRequest {
return ApiGetCveRequest{
ApiService: a,
ctx: ctx,
cVE: cVE,
ctx: ctx,
cVE: cVE,
}
}
@ -167,21 +166,21 @@ func (a *DefaultApiService) GetCveExecute(r ApiGetCveRequest) (CVEDetailed, *_ne
}
type ApiGetCvesRequest struct {
ctx _context.Context
ApiService DefaultApi
before *string
after *string
ids *string
bug *string
advisory *string
severity *string
package_ *string
product *string
cwe *string
cvssScore *string
cvss3Score *string
page *float32
perPage *float32
ctx _context.Context
ApiService DefaultApi
before *string
after *string
ids *string
bug *string
advisory *string
severity *string
package_ *string
product *string
cwe *string
cvssScore *float32
cvss3Score *string
page *float32
perPage *float32
createdDaysAgo *float32
}
@ -221,7 +220,7 @@ func (r ApiGetCvesRequest) Cwe(cwe string) ApiGetCvesRequest {
r.cwe = &cwe
return r
}
func (r ApiGetCvesRequest) CvssScore(cvssScore string) ApiGetCvesRequest {
func (r ApiGetCvesRequest) CvssScore(cvssScore float32) ApiGetCvesRequest {
r.cvssScore = &cvssScore
return r
}
@ -255,7 +254,7 @@ func (r ApiGetCvesRequest) Execute() ([]CVE, *_nethttp.Response, error) {
func (a *DefaultApiService) GetCves(ctx _context.Context) ApiGetCvesRequest {
return ApiGetCvesRequest{
ApiService: a,
ctx: ctx,
ctx: ctx,
}
}

View File

@ -78,9 +78,9 @@ type ServerVariable struct {
// ServerConfiguration stores the information about a server
type ServerConfiguration struct {
URL string
URL string
Description string
Variables map[string]ServerVariable
Variables map[string]ServerVariable
}
// ServerConfigurations stores multiple ServerConfiguration items
@ -101,17 +101,16 @@ type Configuration struct {
// NewConfiguration returns a new Configuration object
func NewConfiguration() *Configuration {
cfg := &Configuration{
DefaultHeader: make(map[string]string),
UserAgent: "OpenAPI-Generator/1.0.0/go",
Debug: false,
Servers: ServerConfigurations{
DefaultHeader: make(map[string]string),
UserAgent: "OpenAPI-Generator/1.0.0/go",
Debug: false,
Servers: ServerConfigurations{
{
URL: "https://access.redhat.com/hydra/rest/securitydata",
URL: "https://access.redhat.com/hydra/rest/securitydata",
Description: "No description provided",
},
},
OperationServers: map[string]ServerConfigurations{
},
OperationServers: map[string]ServerConfigurations{},
}
return cfg
}

View File

@ -10,7 +10,7 @@ Name | Type | Description | Notes
**Advisories** | **[]string** | |
**Bugzilla** | **string** | |
**BugzillaDescription** | **string** | |
**CvssScore** | Pointer to **string** | | [optional]
**CvssScore** | Pointer to **float32** | | [optional]
**CvssScoringVector** | Pointer to **string** | | [optional]
**CWE** | **string** | |
**AffectedPackages** | **[]string** | |
@ -159,20 +159,20 @@ SetBugzillaDescription sets BugzillaDescription field to given value.
### GetCvssScore
`func (o *CVE) GetCvssScore() string`
`func (o *CVE) GetCvssScore() float32`
GetCvssScore returns the CvssScore field if non-nil, zero value otherwise.
### GetCvssScoreOk
`func (o *CVE) GetCvssScoreOk() (*string, bool)`
`func (o *CVE) GetCvssScoreOk() (*float32, bool)`
GetCvssScoreOk returns a tuple with the CvssScore field if it's non-nil, zero value otherwise
and a boolean to check if the value has been set.
### SetCvssScore
`func (o *CVE) SetCvssScore(v string)`
`func (o *CVE) SetCvssScore(v float32)`
SetCvssScore sets CvssScore field to given value.

View File

@ -110,7 +110,7 @@ func main() {
package_ := "package__example" // string | CVEs which affect the package (optional)
product := "product_example" // string | CVEs which affect the product. The parameter supports Perl compatible regular expressions. (optional)
cwe := "cwe_example" // string | CVEs with CWE (optional)
cvssScore := "cvssScore_example" // string | CVEs with CVSS score greater than or equal to this value (optional)
cvssScore := float32(8.14) // float32 | CVEs with CVSS score greater than or equal to this value (optional)
cvss3Score := "cvss3Score_example" // string | CVEs with CVSSv3 score greater than or equal to this value (optional)
page := float32(8.14) // float32 | CVEs for page number (optional)
perPage := float32(8.14) // float32 | Number of CVEs to return per page (optional)
@ -148,7 +148,7 @@ Name | Type | Description | Notes
**package_** | **string** | CVEs which affect the package |
**product** | **string** | CVEs which affect the product. The parameter supports Perl compatible regular expressions. |
**cwe** | **string** | CVEs with CWE |
**cvssScore** | **string** | CVEs with CVSS score greater than or equal to this value |
**cvssScore** | **float32** | CVEs with CVSS score greater than or equal to this value |
**cvss3Score** | **string** | CVEs with CVSSv3 score greater than or equal to this value |
**page** | **float32** | CVEs for page number |
**perPage** | **float32** | Number of CVEs to return per page |

View File

@ -17,19 +17,19 @@ import (
// CVE CVE model used in listing
type CVE struct {
CVE string `json:"CVE"`
Severity string `json:"severity"`
PublicDate string `json:"public_date"`
Advisories []string `json:"advisories"`
Bugzilla string `json:"bugzilla"`
BugzillaDescription string `json:"bugzilla_description"`
CvssScore *string `json:"cvss_score,omitempty"`
CvssScoringVector *string `json:"cvss_scoring_vector,omitempty"`
CWE string `json:"CWE"`
AffectedPackages []string `json:"affected_packages"`
ResourceUrl string `json:"resource_url"`
Cvss3ScoringVector string `json:"cvss3_scoring_vector"`
Cvss3Score string `json:"cvss3_score"`
CVE string `json:"CVE"`
Severity string `json:"severity"`
PublicDate string `json:"public_date"`
Advisories []string `json:"advisories"`
Bugzilla string `json:"bugzilla"`
BugzillaDescription string `json:"bugzilla_description"`
CvssScore *float32 `json:"cvss_score,omitempty"`
CvssScoringVector *string `json:"cvss_scoring_vector,omitempty"`
CWE string `json:"CWE"`
AffectedPackages []string `json:"affected_packages"`
ResourceUrl string `json:"resource_url"`
Cvss3ScoringVector string `json:"cvss3_scoring_vector"`
Cvss3Score string `json:"cvss3_score"`
}
// NewCVE instantiates a new CVE object
@ -73,7 +73,7 @@ func (o *CVE) GetCVE() string {
// GetCVEOk returns a tuple with the CVE field value
// and a boolean to check if the value has been set.
func (o *CVE) GetCVEOk() (*string, bool) {
if o == nil {
if o == nil {
return nil, false
}
return &o.CVE, true
@ -97,7 +97,7 @@ func (o *CVE) GetSeverity() string {
// GetSeverityOk returns a tuple with the Severity field value
// and a boolean to check if the value has been set.
func (o *CVE) GetSeverityOk() (*string, bool) {
if o == nil {
if o == nil {
return nil, false
}
return &o.Severity, true
@ -121,7 +121,7 @@ func (o *CVE) GetPublicDate() string {
// GetPublicDateOk returns a tuple with the PublicDate field value
// and a boolean to check if the value has been set.
func (o *CVE) GetPublicDateOk() (*string, bool) {
if o == nil {
if o == nil {
return nil, false
}
return &o.PublicDate, true
@ -145,7 +145,7 @@ func (o *CVE) GetAdvisories() []string {
// GetAdvisoriesOk returns a tuple with the Advisories field value
// and a boolean to check if the value has been set.
func (o *CVE) GetAdvisoriesOk() (*[]string, bool) {
if o == nil {
if o == nil {
return nil, false
}
return &o.Advisories, true
@ -169,7 +169,7 @@ func (o *CVE) GetBugzilla() string {
// GetBugzillaOk returns a tuple with the Bugzilla field value
// and a boolean to check if the value has been set.
func (o *CVE) GetBugzillaOk() (*string, bool) {
if o == nil {
if o == nil {
return nil, false
}
return &o.Bugzilla, true
@ -193,7 +193,7 @@ func (o *CVE) GetBugzillaDescription() string {
// GetBugzillaDescriptionOk returns a tuple with the BugzillaDescription field value
// and a boolean to check if the value has been set.
func (o *CVE) GetBugzillaDescriptionOk() (*string, bool) {
if o == nil {
if o == nil {
return nil, false
}
return &o.BugzillaDescription, true
@ -205,9 +205,9 @@ func (o *CVE) SetBugzillaDescription(v string) {
}
// GetCvssScore returns the CvssScore field value if set, zero value otherwise.
func (o *CVE) GetCvssScore() string {
func (o *CVE) GetCvssScore() float32 {
if o == nil || o.CvssScore == nil {
var ret string
var ret float32
return ret
}
return *o.CvssScore
@ -215,7 +215,7 @@ func (o *CVE) GetCvssScore() string {
// GetCvssScoreOk returns a tuple with the CvssScore field value if set, nil otherwise
// and a boolean to check if the value has been set.
func (o *CVE) GetCvssScoreOk() (*string, bool) {
func (o *CVE) GetCvssScoreOk() (*float32, bool) {
if o == nil || o.CvssScore == nil {
return nil, false
}
@ -231,8 +231,8 @@ func (o *CVE) HasCvssScore() bool {
return false
}
// SetCvssScore gets a reference to the given string and assigns it to the CvssScore field.
func (o *CVE) SetCvssScore(v string) {
// SetCvssScore gets a reference to the given float32 and assigns it to the CvssScore field.
func (o *CVE) SetCvssScore(v float32) {
o.CvssScore = &v
}
@ -281,7 +281,7 @@ func (o *CVE) GetCWE() string {
// GetCWEOk returns a tuple with the CWE field value
// and a boolean to check if the value has been set.
func (o *CVE) GetCWEOk() (*string, bool) {
if o == nil {
if o == nil {
return nil, false
}
return &o.CWE, true
@ -305,7 +305,7 @@ func (o *CVE) GetAffectedPackages() []string {
// GetAffectedPackagesOk returns a tuple with the AffectedPackages field value
// and a boolean to check if the value has been set.
func (o *CVE) GetAffectedPackagesOk() (*[]string, bool) {
if o == nil {
if o == nil {
return nil, false
}
return &o.AffectedPackages, true
@ -329,7 +329,7 @@ func (o *CVE) GetResourceUrl() string {
// GetResourceUrlOk returns a tuple with the ResourceUrl field value
// and a boolean to check if the value has been set.
func (o *CVE) GetResourceUrlOk() (*string, bool) {
if o == nil {
if o == nil {
return nil, false
}
return &o.ResourceUrl, true
@ -353,7 +353,7 @@ func (o *CVE) GetCvss3ScoringVector() string {
// GetCvss3ScoringVectorOk returns a tuple with the Cvss3ScoringVector field value
// and a boolean to check if the value has been set.
func (o *CVE) GetCvss3ScoringVectorOk() (*string, bool) {
if o == nil {
if o == nil {
return nil, false
}
return &o.Cvss3ScoringVector, true
@ -377,7 +377,7 @@ func (o *CVE) GetCvss3Score() string {
// GetCvss3ScoreOk returns a tuple with the Cvss3Score field value
// and a boolean to check if the value has been set.
func (o *CVE) GetCvss3ScoreOk() (*string, bool) {
if o == nil {
if o == nil {
return nil, false
}
return &o.Cvss3Score, true
@ -467,5 +467,3 @@ func (v *NullableCVE) UnmarshalJSON(src []byte) error {
v.isSet = true
return json.Unmarshal(src, &v.value)
}

View File

@ -17,17 +17,17 @@ import (
// CVEDetailed CVE model used when retrieving a specific CVE
type CVEDetailed struct {
ThreatSeverity string `json:"threat_severity"`
PublicDate string `json:"public_date"`
Bugzilla CVEDetailedBugzilla `json:"bugzilla"`
Cvss3 CVEDetailedCvss3 `json:"cvss3"`
Cwe string `json:"cwe"`
Details []string `json:"details"`
Acknowledgement string `json:"acknowledgement"`
ThreatSeverity string `json:"threat_severity"`
PublicDate string `json:"public_date"`
Bugzilla CVEDetailedBugzilla `json:"bugzilla"`
Cvss3 CVEDetailedCvss3 `json:"cvss3"`
Cwe string `json:"cwe"`
Details []string `json:"details"`
Acknowledgement string `json:"acknowledgement"`
AffectedRelease *[]CVEDetailedAffectedRelease `json:"affected_release,omitempty"`
Name string `json:"name"`
Csaw bool `json:"csaw"`
PackageState *[]CVEDetailedPackageState `json:"package_state,omitempty"`
Name string `json:"name"`
Csaw bool `json:"csaw"`
PackageState *[]CVEDetailedPackageState `json:"package_state,omitempty"`
}
// NewCVEDetailed instantiates a new CVEDetailed object
@ -69,7 +69,7 @@ func (o *CVEDetailed) GetThreatSeverity() string {
// GetThreatSeverityOk returns a tuple with the ThreatSeverity field value
// and a boolean to check if the value has been set.
func (o *CVEDetailed) GetThreatSeverityOk() (*string, bool) {
if o == nil {
if o == nil {
return nil, false
}
return &o.ThreatSeverity, true
@ -93,7 +93,7 @@ func (o *CVEDetailed) GetPublicDate() string {
// GetPublicDateOk returns a tuple with the PublicDate field value
// and a boolean to check if the value has been set.
func (o *CVEDetailed) GetPublicDateOk() (*string, bool) {
if o == nil {
if o == nil {
return nil, false
}
return &o.PublicDate, true
@ -117,7 +117,7 @@ func (o *CVEDetailed) GetBugzilla() CVEDetailedBugzilla {
// GetBugzillaOk returns a tuple with the Bugzilla field value
// and a boolean to check if the value has been set.
func (o *CVEDetailed) GetBugzillaOk() (*CVEDetailedBugzilla, bool) {
if o == nil {
if o == nil {
return nil, false
}
return &o.Bugzilla, true
@ -141,7 +141,7 @@ func (o *CVEDetailed) GetCvss3() CVEDetailedCvss3 {
// GetCvss3Ok returns a tuple with the Cvss3 field value
// and a boolean to check if the value has been set.
func (o *CVEDetailed) GetCvss3Ok() (*CVEDetailedCvss3, bool) {
if o == nil {
if o == nil {
return nil, false
}
return &o.Cvss3, true
@ -165,7 +165,7 @@ func (o *CVEDetailed) GetCwe() string {
// GetCweOk returns a tuple with the Cwe field value
// and a boolean to check if the value has been set.
func (o *CVEDetailed) GetCweOk() (*string, bool) {
if o == nil {
if o == nil {
return nil, false
}
return &o.Cwe, true
@ -189,7 +189,7 @@ func (o *CVEDetailed) GetDetails() []string {
// GetDetailsOk returns a tuple with the Details field value
// and a boolean to check if the value has been set.
func (o *CVEDetailed) GetDetailsOk() (*[]string, bool) {
if o == nil {
if o == nil {
return nil, false
}
return &o.Details, true
@ -213,7 +213,7 @@ func (o *CVEDetailed) GetAcknowledgement() string {
// GetAcknowledgementOk returns a tuple with the Acknowledgement field value
// and a boolean to check if the value has been set.
func (o *CVEDetailed) GetAcknowledgementOk() (*string, bool) {
if o == nil {
if o == nil {
return nil, false
}
return &o.Acknowledgement, true
@ -269,7 +269,7 @@ func (o *CVEDetailed) GetName() string {
// GetNameOk returns a tuple with the Name field value
// and a boolean to check if the value has been set.
func (o *CVEDetailed) GetNameOk() (*string, bool) {
if o == nil {
if o == nil {
return nil, false
}
return &o.Name, true
@ -293,7 +293,7 @@ func (o *CVEDetailed) GetCsaw() bool {
// GetCsawOk returns a tuple with the Csaw field value
// and a boolean to check if the value has been set.
func (o *CVEDetailed) GetCsawOk() (*bool, bool) {
if o == nil {
if o == nil {
return nil, false
}
return &o.Csaw, true
@ -409,5 +409,3 @@ func (v *NullableCVEDetailed) UnmarshalJSON(src []byte) error {
v.isSet = true
return json.Unmarshal(src, &v.value)
}

View File

@ -17,11 +17,11 @@ import (
// CVEDetailedAffectedRelease struct for CVEDetailedAffectedRelease
type CVEDetailedAffectedRelease struct {
ProductName string `json:"product_name"`
ReleaseDate string `json:"release_date"`
Advisory string `json:"advisory"`
Cpe string `json:"cpe"`
Package *string `json:"package,omitempty"`
ProductName string `json:"product_name"`
ReleaseDate string `json:"release_date"`
Advisory string `json:"advisory"`
Cpe string `json:"cpe"`
Package *string `json:"package,omitempty"`
}
// NewCVEDetailedAffectedRelease instantiates a new CVEDetailedAffectedRelease object
@ -58,7 +58,7 @@ func (o *CVEDetailedAffectedRelease) GetProductName() string {
// GetProductNameOk returns a tuple with the ProductName field value
// and a boolean to check if the value has been set.
func (o *CVEDetailedAffectedRelease) GetProductNameOk() (*string, bool) {
if o == nil {
if o == nil {
return nil, false
}
return &o.ProductName, true
@ -82,7 +82,7 @@ func (o *CVEDetailedAffectedRelease) GetReleaseDate() string {
// GetReleaseDateOk returns a tuple with the ReleaseDate field value
// and a boolean to check if the value has been set.
func (o *CVEDetailedAffectedRelease) GetReleaseDateOk() (*string, bool) {
if o == nil {
if o == nil {
return nil, false
}
return &o.ReleaseDate, true
@ -106,7 +106,7 @@ func (o *CVEDetailedAffectedRelease) GetAdvisory() string {
// GetAdvisoryOk returns a tuple with the Advisory field value
// and a boolean to check if the value has been set.
func (o *CVEDetailedAffectedRelease) GetAdvisoryOk() (*string, bool) {
if o == nil {
if o == nil {
return nil, false
}
return &o.Advisory, true
@ -130,7 +130,7 @@ func (o *CVEDetailedAffectedRelease) GetCpe() string {
// GetCpeOk returns a tuple with the Cpe field value
// and a boolean to check if the value has been set.
func (o *CVEDetailedAffectedRelease) GetCpeOk() (*string, bool) {
if o == nil {
if o == nil {
return nil, false
}
return &o.Cpe, true
@ -228,5 +228,3 @@ func (v *NullableCVEDetailedAffectedRelease) UnmarshalJSON(src []byte) error {
v.isSet = true
return json.Unmarshal(src, &v.value)
}

View File

@ -18,8 +18,8 @@ import (
// CVEDetailedBugzilla struct for CVEDetailedBugzilla
type CVEDetailedBugzilla struct {
Description string `json:"description"`
Id string `json:"id"`
Url string `json:"url"`
Id string `json:"id"`
Url string `json:"url"`
}
// NewCVEDetailedBugzilla instantiates a new CVEDetailedBugzilla object
@ -55,7 +55,7 @@ func (o *CVEDetailedBugzilla) GetDescription() string {
// GetDescriptionOk returns a tuple with the Description field value
// and a boolean to check if the value has been set.
func (o *CVEDetailedBugzilla) GetDescriptionOk() (*string, bool) {
if o == nil {
if o == nil {
return nil, false
}
return &o.Description, true
@ -79,7 +79,7 @@ func (o *CVEDetailedBugzilla) GetId() string {
// GetIdOk returns a tuple with the Id field value
// and a boolean to check if the value has been set.
func (o *CVEDetailedBugzilla) GetIdOk() (*string, bool) {
if o == nil {
if o == nil {
return nil, false
}
return &o.Id, true
@ -103,7 +103,7 @@ func (o *CVEDetailedBugzilla) GetUrl() string {
// GetUrlOk returns a tuple with the Url field value
// and a boolean to check if the value has been set.
func (o *CVEDetailedBugzilla) GetUrlOk() (*string, bool) {
if o == nil {
if o == nil {
return nil, false
}
return &o.Url, true
@ -163,5 +163,3 @@ func (v *NullableCVEDetailedBugzilla) UnmarshalJSON(src []byte) error {
v.isSet = true
return json.Unmarshal(src, &v.value)
}

View File

@ -17,9 +17,9 @@ import (
// CVEDetailedCvss3 struct for CVEDetailedCvss3
type CVEDetailedCvss3 struct {
Cvss3BaseScore string `json:"cvss3_base_score"`
Cvss3BaseScore string `json:"cvss3_base_score"`
Cvss3ScoringVector string `json:"cvss3_scoring_vector"`
Status string `json:"status"`
Status string `json:"status"`
}
// NewCVEDetailedCvss3 instantiates a new CVEDetailedCvss3 object
@ -55,7 +55,7 @@ func (o *CVEDetailedCvss3) GetCvss3BaseScore() string {
// GetCvss3BaseScoreOk returns a tuple with the Cvss3BaseScore field value
// and a boolean to check if the value has been set.
func (o *CVEDetailedCvss3) GetCvss3BaseScoreOk() (*string, bool) {
if o == nil {
if o == nil {
return nil, false
}
return &o.Cvss3BaseScore, true
@ -79,7 +79,7 @@ func (o *CVEDetailedCvss3) GetCvss3ScoringVector() string {
// GetCvss3ScoringVectorOk returns a tuple with the Cvss3ScoringVector field value
// and a boolean to check if the value has been set.
func (o *CVEDetailedCvss3) GetCvss3ScoringVectorOk() (*string, bool) {
if o == nil {
if o == nil {
return nil, false
}
return &o.Cvss3ScoringVector, true
@ -103,7 +103,7 @@ func (o *CVEDetailedCvss3) GetStatus() string {
// GetStatusOk returns a tuple with the Status field value
// and a boolean to check if the value has been set.
func (o *CVEDetailedCvss3) GetStatusOk() (*string, bool) {
if o == nil {
if o == nil {
return nil, false
}
return &o.Status, true
@ -163,5 +163,3 @@ func (v *NullableCVEDetailedCvss3) UnmarshalJSON(src []byte) error {
v.isSet = true
return json.Unmarshal(src, &v.value)
}

View File

@ -18,9 +18,9 @@ import (
// CVEDetailedPackageState struct for CVEDetailedPackageState
type CVEDetailedPackageState struct {
ProductName string `json:"product_name"`
FixState string `json:"fix_state"`
FixState string `json:"fix_state"`
PackageName string `json:"package_name"`
Cpe string `json:"cpe"`
Cpe string `json:"cpe"`
}
// NewCVEDetailedPackageState instantiates a new CVEDetailedPackageState object
@ -57,7 +57,7 @@ func (o *CVEDetailedPackageState) GetProductName() string {
// GetProductNameOk returns a tuple with the ProductName field value
// and a boolean to check if the value has been set.
func (o *CVEDetailedPackageState) GetProductNameOk() (*string, bool) {
if o == nil {
if o == nil {
return nil, false
}
return &o.ProductName, true
@ -81,7 +81,7 @@ func (o *CVEDetailedPackageState) GetFixState() string {
// GetFixStateOk returns a tuple with the FixState field value
// and a boolean to check if the value has been set.
func (o *CVEDetailedPackageState) GetFixStateOk() (*string, bool) {
if o == nil {
if o == nil {
return nil, false
}
return &o.FixState, true
@ -105,7 +105,7 @@ func (o *CVEDetailedPackageState) GetPackageName() string {
// GetPackageNameOk returns a tuple with the PackageName field value
// and a boolean to check if the value has been set.
func (o *CVEDetailedPackageState) GetPackageNameOk() (*string, bool) {
if o == nil {
if o == nil {
return nil, false
}
return &o.PackageName, true
@ -129,7 +129,7 @@ func (o *CVEDetailedPackageState) GetCpe() string {
// GetCpeOk returns a tuple with the Cpe field value
// and a boolean to check if the value has been set.
func (o *CVEDetailedPackageState) GetCpeOk() (*string, bool) {
if o == nil {
if o == nil {
return nil, false
}
return &o.Cpe, true
@ -192,5 +192,3 @@ func (v *NullableCVEDetailedPackageState) UnmarshalJSON(src []byte) error {
v.isSet = true
return json.Unmarshal(src, &v.value)
}

Some files were not shown because too many files have changed in this diff Show More