Delete Apollo from this repo

This commit is contained in:
Mustafa Gezen 2023-02-17 19:35:58 +01:00
parent 808a48a80d
commit 032909173e
Signed by untrusted user who does not match committer: mustafa
GPG Key ID: DCDF010D946438C1
107 changed files with 2 additions and 13201 deletions

2
apollo/README.md Normal file
View File

@ -0,0 +1,2 @@
# Apollo has moved
Apollo v3 lives in distro-tools at https://github.com/resf/distro-tools

View File

@ -1,21 +0,0 @@
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

@ -1,21 +0,0 @@
load("//rules_resf:defs.bzl", "RESFDEPLOY_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 = RESFDEPLOY_OUTS_MIGRATE,
chart_yaml = "Chart.yaml",
values_yaml = "values.yaml",
deps = ["//ci"],
)

View File

@ -1,6 +0,0 @@
apiVersion: v2
name: apollo
description: Helm chart for apollo
type: application
version: 0.0.1
appVersion: "0.0.1"

View File

@ -1,48 +0,0 @@
local resfdeploy = import 'ci/resfdeploy.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';
resfdeploy.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

@ -1,3 +0,0 @@
# Ports under requires ingressHost to be set during deploy
http:
ingressHost: null

View File

@ -1,67 +0,0 @@
// 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"
apolloconnector "peridot.resf.org/apollo/db/connector"
apolloimpl "peridot.resf.org/apollo/impl/v1"
"peridot.resf.org/utils"
)
var root = &cobra.Command{
Use: "apollo",
Run: mn,
}
var cnf = utils.NewFlagConfig()
func init() {
cnf.DefaultPort = 9100
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) {
apolloimpl.NewServer(apolloconnector.MustAuto()).Run()
}
func main() {
utils.Main()
if err := root.Execute(); err != nil {
logrus.Fatal(err)
}
}

View File

@ -1,24 +0,0 @@
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

@ -1,20 +0,0 @@
load("//rules_resf:defs.bzl", "RESFDEPLOY_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 = RESFDEPLOY_OUTS_MIGRATE,
chart_yaml = "Chart.yaml",
values_yaml = "values.yaml",
deps = [
"//ci",
],
)

View File

@ -1,6 +0,0 @@
apiVersion: v2
name: apollostarter
description: Helm chart for apollostarter
type: application
version: 0.0.1
appVersion: "0.0.1"

View File

@ -1,46 +0,0 @@
local resfdeploy = import 'ci/resfdeploy.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');
resfdeploy.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

@ -1 +0,0 @@
temporalHostPort: workflow-temporal-frontend.workflow.svc.cluster.local:7233

View File

@ -1,153 +0,0 @@
// 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

@ -1,27 +0,0 @@
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

@ -1,20 +0,0 @@
load("//rules_resf:defs.bzl", "RESFDEPLOY_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 = RESFDEPLOY_OUTS_MIGRATE,
chart_yaml = "Chart.yaml",
values_yaml = "values.yaml",
deps = [
"//ci",
],
)

View File

@ -1,6 +0,0 @@
apiVersion: v2
name: apolloworker
description: Helm chart for apolloworker
type: application
version: 0.0.1
appVersion: "0.0.1"

View File

@ -1,46 +0,0 @@
local resfdeploy = import 'ci/resfdeploy.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');
resfdeploy.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

@ -1 +0,0 @@
temporalHostPort: workflow-temporal-frontend.workflow.svc.cluster.local:7233

View File

@ -1,143 +0,0 @@
// 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

@ -1,19 +0,0 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "db",
srcs = [
"convert.go",
"db.go",
],
importpath = "peridot.resf.org/apollo/db",
visibility = ["//visibility:public"],
deps = [
"//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

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

View File

@ -1,50 +0,0 @@
// 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 apolloconnector
import (
"github.com/sirupsen/logrus"
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() apollodb.Access {
dbType := utils.GetDbType()
switch dbType {
case utils.DbPostgres:
return apollopsql.New()
default:
logrus.Fatal("invalid database url supplied")
return nil
}
}

View File

@ -1,155 +0,0 @@
// 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 apollodb
import (
"fmt"
"google.golang.org/protobuf/types/known/timestamppb"
"google.golang.org/protobuf/types/known/wrapperspb"
apollopb "peridot.resf.org/apollo/pb"
"strings"
)
func DTOAdvisoryToPB(sc *Advisory) *apollopb.Advisory {
var errataType string
switch apollopb.Advisory_Type(sc.Type) {
case apollopb.Advisory_TYPE_SECURITY:
errataType = "SA"
break
case apollopb.Advisory_TYPE_BUGFIX:
errataType = "BA"
break
case apollopb.Advisory_TYPE_ENHANCEMENT:
errataType = "EA"
break
default:
errataType = "UNK"
break
}
var publishedAt *timestamppb.Timestamp
if sc.PublishedAt.Valid {
publishedAt = timestamppb.New(sc.PublishedAt.Time)
}
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: apollopb.Advisory_Severity(sc.Severity),
Topic: sc.Topic,
Description: sc.Description,
AffectedProducts: sc.AffectedProducts,
Fixes: nil,
Cves: []*apollopb.CVE{},
References: sc.References,
PublishedAt: publishedAt,
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{}
}
ret.Rpms[productName].Nvras = append(ret.Rpms[productName].Nvras, nvra)
}
return ret
}
func DTOListAdvisoriesToPB(scs []*Advisory) []*apollopb.Advisory {
var ret []*apollopb.Advisory
for _, v := range scs {
ret = append(ret, DTOAdvisoryToPB(v))
}
return ret
}
func DTOCVEToPB(cve *CVE) *apollopb.CVE {
ret := &apollopb.CVE{
Name: cve.ID,
}
if cve.SourceBy.Valid {
ret.SourceBy = wrapperspb.String(cve.SourceBy.String)
}
if cve.SourceLink.Valid {
ret.SourceLink = wrapperspb.String(cve.SourceLink.String)
}
return ret
}
func DTOListCVEsToPB(cves []*CVE) []*apollopb.CVE {
var ret []*apollopb.CVE
for _, v := range cves {
ret = append(ret, DTOCVEToPB(v))
}
return ret
}

View File

@ -1,251 +0,0 @@
// 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 apollodb
import (
"database/sql"
"github.com/jmoiron/sqlx/types"
"github.com/lib/pq"
apollopb "peridot.resf.org/apollo/pb"
"peridot.resf.org/utils"
"time"
)
// ShortCode is the DTO struct for `resf.apollo.ShortCode`
type ShortCode struct {
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.apollo.Advisory`
type Advisory struct {
ID int64 `db:"id"`
CreatedAt *time.Time `db:"created_at"`
Year int `db:"year"`
Num int `db:"num"`
Synopsis string `db:"synopsis"`
Topic string `db:"topic"`
Severity int `db:"severity"`
Type int `db:"type"`
Description string `db:"description"`
Solution sql.NullString `db:"solution"`
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.apollo.CVE`
type CVE struct {
ID string `db:"id"`
CreatedAt *time.Time `db:"created_at"`
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 `resf.apollo.AffectedProduct`
type AffectedProduct struct {
ID int64 `db:"id"`
ProductID int64 `db:"product_id"`
CveID sql.NullString `db:"cve_id"`
State int `db:"state"`
Version string `db:"version"`
Package string `db:"package"`
Advisory sql.NullString `db:"advisory"`
}
// 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"`
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"`
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"`
}
type AdvisoryReference struct {
ID int64 `db:"advisory_reference"`
URL string `db:"url"`
AdvisoryId int64 `db:"advisory_id"`
}
type MirrorState struct {
ShortCode string `db:"short_code_code"`
LastSync sql.NullTime `db:"last_sync"`
ErrataAfter sql.NullTime `db:"errata_after"`
}
type AdvisoryCVE struct {
AdvisoryID int64 `db:"advisory_id"`
CveID string `db:"cve_id"`
}
type AdvisoryFix struct {
AdvisoryID int64 `db:"advisory_id"`
FixID int64 `db:"fix_id"`
}
type IgnoredUpstreamPackage struct {
ID int64 `db:"id"`
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 apollopb.ShortCode_Mode) (*ShortCode, 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.
// Obviously fields like ID and CreatedAt cannot be overridden
// The Create and Update methods for advisory do not return
// the following fields:
// - AffectedProducts
// - Fixes
// - Cves
// - References
CreateAdvisory(advisory *Advisory) (*Advisory, error)
// Update cannot override the RedHatIssuedAt field for mirrored advisories
UpdateAdvisory(advisory *Advisory) (*Advisory, error)
GetAdvisoryByCodeAndYearAndNum(code string, year int, num int) (*Advisory, error)
GetAllUnresolvedCVEs() ([]*CVE, error)
GetPendingAffectedProducts() ([]*AffectedProduct, error)
GetAllCVEsFixedDownstream() ([]*CVE, error)
GetCVEByID(id string) (*CVE, 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)
GetProductByID(id int64) (*Product, error)
CreateProduct(name string, currentFullVersion string, redHatMajorVersion *int32, code string, archs []string) (*Product, error)
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, sourceBy string, sourceLink string, description string) (int64, error)
// This will return nil rather than an error if no rows are found
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, sha256Sum string, kojiId *string, peridotId *string) (*BuildReference, error)
CreateAdvisoryReference(advisoryId int64, url 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, productID int64) error
Begin() (utils.Tx, error)
UseTransaction(tx utils.Tx) Access
}

View File

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

View File

@ -1,774 +0,0 @@
// 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 apollomock
import (
"database/sql"
"fmt"
"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 []*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: []*apollodb.ShortCode{},
Advisories: []*apollodb.Advisory{},
Cves: []*apollodb.CVE{},
Fixes: []*apollodb.Fix{},
AdvisoryReferences: []*apollodb.AdvisoryReference{},
Products: []*apollodb.Product{},
AffectedProducts: []*apollodb.AffectedProduct{},
BuildReferences: []*apollodb.BuildReference{},
MirrorStates: []*apollodb.MirrorState{},
AdvisoryCVEs: []*apollodb.AdvisoryCVE{},
AdvisoryFixes: []*apollodb.AdvisoryFix{},
IgnoredUpstreamPackages: []*apollodb.IgnoredUpstreamPackage{},
RebootSuggestedPackages: []*apollodb.RebootSuggestedPackage{},
AdvisoryRPMs: []*apollodb.AdvisoryRPM{},
}
}
func (a *Access) GetAllShortCodes() ([]*apollodb.ShortCode, error) {
return a.ShortCodes, nil
}
func (a *Access) GetShortCodeByCode(code string) (*apollodb.ShortCode, error) {
for _, val := range a.ShortCodes {
if val.Code == code {
return val, nil
}
}
return nil, sql.ErrNoRows
}
func (a *Access) CreateShortCode(code string, mode apollopb.ShortCode_Mode) (*apollodb.ShortCode, error) {
now := time.Now()
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(*apollodb.Advisory) bool) []*apollodb.Advisory {
var advisories []*apollodb.Advisory
for _, val := range a.Advisories {
if filter(val) {
advisories = append(advisories, val)
}
}
if len(advisories) == 0 {
return advisories
}
for _, advisory := range advisories {
advisory.AffectedProducts = []string{}
advisory.Fixes = []string{}
advisory.Cves = []string{}
advisory.References = []string{}
advisory.RPMs = []string{}
advisory.BuildArtifacts = []string{}
for _, advisoryCve := range a.AdvisoryCVEs {
if advisoryCve.AdvisoryID != advisory.ID {
continue
}
for _, buildReference := range a.BuildReferences {
if buildReference.CveID == advisoryCve.CveID {
advisory.BuildArtifacts = append(advisory.BuildArtifacts, fmt.Sprintf("%s:::%s", buildReference.Rpm, buildReference.SrcRpm))
}
}
for _, cve := range a.Cves {
if cve.ID == advisoryCve.CveID {
cveString := fmt.Sprintf("%s:::%s:::%s", cve.SourceBy.String, cve.SourceLink.String, cve.ID)
if !utils.StrContains(cveString, advisory.Cves) {
advisory.Cves = append(advisory.Cves, cveString)
}
}
}
for _, val := range a.AffectedProducts {
if val.CveID.String == advisoryCve.CveID {
for _, product := range a.Products {
if val.ProductID == product.ID {
if !utils.StrContains(product.Name, advisory.AffectedProducts) {
advisory.AffectedProducts = append(advisory.AffectedProducts, product.Name)
}
}
}
}
}
}
for _, advisoryFix := range a.AdvisoryFixes {
if advisoryFix.AdvisoryID != advisory.ID {
continue
}
for _, fix := range a.Fixes {
if fix.ID == advisoryFix.FixID {
if !utils.StrContains(fix.Ticket.String, advisory.Fixes) {
advisory.Fixes = append(advisory.Fixes, fix.Ticket.String)
}
}
}
}
for _, advisoryReference := range a.AdvisoryReferences {
if advisoryReference.AdvisoryId != advisory.ID {
continue
}
if !utils.StrContains(advisoryReference.URL, advisory.References) {
advisory.References = append(advisory.References, advisoryReference.URL)
}
}
for _, advisoryRPM := range a.AdvisoryRPMs {
if advisoryRPM.AdvisoryID != advisory.ID {
continue
}
if !utils.StrContains(advisoryRPM.Name, advisory.RPMs) {
advisory.RPMs = append(advisory.RPMs, advisoryRPM.Name)
}
}
}
return advisories
}
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
}
}
if advisory.Fixes != nil && len(advisory.Fixes) < 1 {
return false
}
return true
}), nil
}
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
}
return false
})
if len(advisories) == 0 {
return nil, sql.ErrNoRows
}
advisory := advisories[0]
if advisory.Fixes != nil && len(advisory.Fixes) < 1 {
return nil, fmt.Errorf("Expected advisory fixes. Was empty.")
}
return advisory, nil
}
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 := &apollodb.Advisory{
ID: lastId,
CreatedAt: &now,
Year: advisory.Year,
Num: advisory.Num,
Synopsis: advisory.Synopsis,
Topic: advisory.Topic,
Severity: advisory.Severity,
Type: advisory.Type,
Description: advisory.Description,
Solution: advisory.Solution,
RedHatIssuedAt: advisory.RedHatIssuedAt,
ShortCodeCode: advisory.ShortCodeCode,
PublishedAt: advisory.PublishedAt,
}
return ret, nil
}
func (a *Access) UpdateAdvisory(advisory *apollodb.Advisory) (*apollodb.Advisory, error) {
for _, val := range a.Advisories {
if val.ID == advisory.ID {
val.Year = advisory.Year
val.Num = advisory.Num
val.Synopsis = advisory.Synopsis
val.Topic = advisory.Topic
val.Severity = advisory.Severity
val.Type = advisory.Type
val.Description = advisory.Description
val.Solution = advisory.Solution
val.ShortCodeCode = advisory.ShortCodeCode
val.PublishedAt = advisory.PublishedAt
return val, nil
}
}
return nil, sql.ErrNoRows
}
func (a *Access) GetAllUnresolvedCVEs() ([]*apollodb.CVE, error) {
var cves []*apollodb.CVE
var addedCVEIds []string
for _, cve := range a.Cves {
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)
}
}
return cves, nil
}
func (a *Access) GetPendingAffectedProducts() ([]*apollodb.AffectedProduct, error) {
var ret []*apollodb.AffectedProduct
for _, affectedProduct := range a.AffectedProducts {
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 {
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
}
}
}
}
return cves, nil
}
func (a *Access) GetCVEByID(id string) (*apollodb.CVE, error) {
for _, cve := range a.Cves {
if cve.ID == id {
return cve, nil
}
}
return nil, sql.ErrNoRows
}
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
if sourceBy != nil {
sby.String = *sourceBy
sby.Valid = true
}
if sourceLink != nil {
sl.String = *sourceLink
sl.Valid = true
}
now := time.Now()
cve := &apollodb.CVE{
ID: cveId,
CreatedAt: &now,
AdvisoryId: sql.NullInt64{},
ShortCode: shortCode,
SourceBy: sby,
SourceLink: sl,
Content: content,
}
a.Cves = append(a.Cves, cve)
return cve, nil
}
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 sql.ErrNoRows
}
func (a *Access) GetProductsByShortCode(code string) ([]*apollodb.Product, error) {
var products []*apollodb.Product
for _, product := range a.Products {
if product.ShortCode == code {
products = append(products, product)
}
}
return products, nil
}
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
}
}
return nil, sql.ErrNoRows
}
func (a *Access) GetProductByID(id int64) (*apollodb.Product, error) {
for _, product := range a.Products {
if product.ID == id {
return product, nil
}
}
return nil, sql.ErrNoRows
}
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
}
var rhmv sql.NullInt32
if redHatMajorVersion != nil {
rhmv.Int32 = *redHatMajorVersion
rhmv.Valid = true
}
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) ([]*apollodb.AffectedProduct, error) {
var affectedProducts []*apollodb.AffectedProduct
for _, affectedProduct := range a.AffectedProducts {
if affectedProduct.CveID.String == cve {
affectedProducts = append(affectedProducts, affectedProduct)
}
}
return affectedProducts, nil
}
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
}
}
return nil, sql.ErrNoRows
}
func (a *Access) GetAffectedProductByAdvisory(advisory string) (*apollodb.AffectedProduct, error) {
for _, affectedProduct := range a.AffectedProducts {
if affectedProduct.Advisory.String == advisory {
return affectedProduct, nil
}
}
return nil, sql.ErrNoRows
}
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
}
var adv sql.NullString
if advisory != nil {
adv.String = *advisory
adv.Valid = true
}
affectedProduct := &apollodb.AffectedProduct{
ID: lastId,
ProductID: productId,
CveID: sql.NullString{Valid: true, String: cveId},
State: state,
Version: version,
Package: pkg,
Advisory: adv,
}
a.AffectedProducts = append(a.AffectedProducts, affectedProduct)
return affectedProduct, nil
}
func (a *Access) UpdateAffectedProductStateAndPackageAndAdvisory(id int64, state int, pkg string, advisory *string) error {
for _, affectedProduct := range a.AffectedProducts {
if affectedProduct.ID == id {
affectedProduct.State = state
affectedProduct.Package = pkg
var adv sql.NullString
if advisory != nil {
adv.String = *advisory
adv.Valid = true
}
affectedProduct.Advisory = adv
return nil
}
}
return sql.ErrNoRows
}
func (a *Access) DeleteAffectedProduct(id int64) error {
var index *int
for i, affectedProduct := range a.AffectedProducts {
if affectedProduct.ID == id {
index = &i
}
}
if index == nil {
return sql.ErrNoRows
}
a.AffectedProducts = append(a.AffectedProducts[:*index], a.AffectedProducts[*index+1:]...)
return nil
}
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 := &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)
return lastId, nil
}
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
}
}
}
if lastSync == nil {
return nil, sql.ErrNoRows
}
return lastSync, nil
}
func (a *Access) UpdateMirrorState(code string, lastSync *time.Time) error {
for _, mirrorState := range a.MirrorStates {
if mirrorState.ShortCode == code {
mirrorState.LastSync.Time = *lastSync
mirrorState.LastSync.Valid = true
return nil
}
}
mirrorState := &apollodb.MirrorState{
ShortCode: code,
LastSync: sql.NullTime{Valid: true, Time: *lastSync},
}
a.MirrorStates = append(a.MirrorStates, mirrorState)
return nil
}
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 := &apollodb.BuildReference{
ID: lastId,
AffectedProductId: affectedProductId,
Rpm: rpm,
SrcRpm: srcRpm,
CveID: cveId,
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)
return buildReference, nil
}
func (a *Access) CreateAdvisoryReference(advisoryId int64, url string) error {
var lastId int64 = 1
if len(a.AdvisoryReferences) > 0 {
lastId = a.AdvisoryReferences[len(a.AdvisoryReferences)-1].ID + 1
}
advisoryReference := &apollodb.AdvisoryReference{
ID: lastId,
URL: url,
AdvisoryId: advisoryId,
}
a.AdvisoryReferences = append(a.AdvisoryReferences, advisoryReference)
return nil
}
func (a *Access) GetAllIgnoredPackagesByProductID(productID int64) ([]string, error) {
var packages []string
for _, ignoredPackage := range a.IgnoredUpstreamPackages {
if ignoredPackage.ProductID == productID {
packages = append(packages, ignoredPackage.Package)
}
}
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 := &apollodb.AdvisoryFix{
AdvisoryID: advisoryId,
FixID: fixId,
}
a.AdvisoryFixes = append(a.AdvisoryFixes, advisoryFix)
return nil
}
func (a *Access) AddAdvisoryCVE(advisoryId int64, cveId string) error {
advisoryCVE := &apollodb.AdvisoryCVE{
AdvisoryID: advisoryId,
CveID: cveId,
}
a.AdvisoryCVEs = append(a.AdvisoryCVEs, advisoryCVE)
return nil
}
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)
return nil
}
func (a *Access) Begin() (utils.Tx, error) {
return &utils.MockTx{}, nil
}
func (a *Access) UseTransaction(_ utils.Tx) apollodb.Access {
return a
}

View File

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

View File

@ -1,797 +0,0 @@
// 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
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,
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 ($5 :: text is null or exists (select cve_id from advisory_cves where advisory_id = a.id and cve_id ilike '%' || $5 :: text || '%'))
and ($6 :: text is null or a.synopsis ilike '%' || $6 :: text || '%')
and ($8 :: text is null or ((a.synopsis ilike '%' || $8 :: text || '%') or (a.topic ilike '%' || $8 :: text || '%') or (a.description ilike '%' || $8 :: text || '%') or (a.solution ilike '%' || $8 :: text || '%') or exists (select cve_id from advisory_cves where advisory_id = a.id and cve_id ilike '%' || $8 :: text || '%') or (a.short_code_code || (case when a.type=1 then 'SA' when a.type=2 then 'BA' else 'EA' end) || '-' || a.year || ':' || a.num ilike '%' || $8 :: 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
`,
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

@ -1,26 +0,0 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "impl",
srcs = [
"advisory.go",
"server.go",
],
importpath = "peridot.resf.org/apollo/impl/v1",
visibility = ["//visibility:public"],
deps = [
"//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",
],
)

View File

@ -1,185 +0,0 @@
// 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"
)
// ListAdvisories returns advisories with given filters
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
}
// ListAdvisoriesRSS returns advisories in RSS format. Only returns latest 25 published advisories
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
}
// GetAdvisory returns a single advisory by name
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

@ -1,98 +0,0 @@
// 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"
"github.com/sirupsen/logrus"
"github.com/spf13/viper"
"google.golang.org/grpc"
apollodb "peridot.resf.org/apollo/db"
apollopb "peridot.resf.org/apollo/pb"
commonpb "peridot.resf.org/common"
"peridot.resf.org/utils"
)
type Server struct {
apollopb.UnimplementedApolloServiceServer
log *logrus.Logger
db apollodb.Access
rssFeedTitle string
rssFeedDescription string
homepage string
}
// NewServer creates a new Apollo server.
func NewServer(db apollodb.Access) *Server {
return &Server{
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
return n(ctx, req, usi, handler)
}
func (s *Server) Run() {
res := utils.NewGRPCServer(
&utils.GRPCOptions{
Interceptor: s.interceptor,
},
func(r *utils.Register) {
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) {
commonpb.RegisterHealthCheckServiceServer(r.Server, &utils.HealthServer{})
apollopb.RegisterApolloServiceServer(r.Server, s)
},
)
defer res.Cancel()
res.WaitGroup.Wait()
}

View File

@ -1,33 +0,0 @@
/*
* 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.
*/
drop table short_codes;

View File

@ -1,40 +0,0 @@
/*
* 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.
*/
create table short_codes
(
code text not null primary key,
mode numeric not null,
created_at timestamp default now() not null,
archived_at timestamp
);

View File

@ -1,33 +0,0 @@
/*
* 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.
*/
drop table products;

View File

@ -1,51 +0,0 @@
/*
* 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.
*/
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,
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

@ -1,33 +0,0 @@
/*
* 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.
*/
drop table advisories;

View File

@ -1,52 +0,0 @@
/*
* 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.
*/
create table advisories
(
id bigserial primary key not null,
created_at timestamp default now() 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,
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

@ -1,33 +0,0 @@
/*
* 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.
*/
drop table cves;

View File

@ -1,41 +0,0 @@
/*
* 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.
*/
create table cves
(
id text primary key,
created_at timestamp default now() not null,
short_code_code text references short_codes (code) not null,
source_by text,
source_link text
)

View File

@ -1,33 +0,0 @@
/*
* 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.
*/
drop table fixes;

View File

@ -1,40 +0,0 @@
/*
* 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.
*/
create table fixes
(
id bigserial primary key,
ticket text,
source_by text,
source_link text,
description text
)

View File

@ -1,33 +0,0 @@
/*
* 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.
*/
drop table advisory_references;

View File

@ -1,38 +0,0 @@
/*
* 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.
*/
create table advisory_references
(
id bigserial primary key,
url text not null,
advisory_id bigint references advisories (id) not null
)

View File

@ -1,33 +0,0 @@
/*
* 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.
*/
drop table affected_products;

View File

@ -1,42 +0,0 @@
/*
* 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.
*/
create table affected_products
(
id bigserial primary key,
product_id bigint references products (id) not null,
cve_id text references cves (id) not null,
state numeric not null,
version text not null,
package text not null,
advisory text
)

View File

@ -1,33 +0,0 @@
/*
* 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.
*/
drop table build_references;

View File

@ -1,43 +0,0 @@
/*
* 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.
*/
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,
sha256_sum text not null,
koji_id text,
peridot_id text
)

View File

@ -1,33 +0,0 @@
/*
* 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.
*/
drop table mirror_state;

View File

@ -1,38 +0,0 @@
/*
* 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.
*/
create table mirror_state
(
short_code_code text references short_codes (code) primary key,
last_sync timestamp,
errata_after timestamp
);

View File

@ -1,33 +0,0 @@
/*
* 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.
*/
drop table advisory_cves;

View File

@ -1,39 +0,0 @@
/*
* 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.
*/
create table advisory_cves
(
advisory_id bigint references advisories (id) not null,
cve_id text references cves (id) not null,
unique (advisory_id, cve_id)
)

View File

@ -1,33 +0,0 @@
/*
* 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.
*/
drop table advisory_fixes;

View File

@ -1,39 +0,0 @@
/*
* 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.
*/
create table advisory_fixes
(
advisory_id bigint references advisories (id) not null,
fix_id bigint references fixes (id) not null,
unique (advisory_id, fix_id)
)

View File

@ -1,33 +0,0 @@
/*
* 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.
*/
drop table ignored_upstream_packages;

View File

@ -1,38 +0,0 @@
/*
* 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.
*/
create table ignored_upstream_packages
(
id bigserial primary key,
product_id bigint references products (id) not null,
package text not null
);

View File

@ -1,33 +0,0 @@
/*
* 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.
*/
drop table advisory_rpms;

View File

@ -1,40 +0,0 @@
/*
* 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.
*/
create table advisory_rpms
(
advisory_id bigint references advisories (id) not null,
name text not null,
product_id bigint references products (id) not null,
unique (advisory_id, name)
)

View File

@ -1,33 +0,0 @@
/*
* 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.
*/
drop table updateinfo_history;

View File

@ -1,37 +0,0 @@
/*
* 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.
*/
create table updateinfo_history
(
repo text primary key,
xml text not null
);

View File

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

View File

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

View File

@ -1,9 +0,0 @@
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

@ -1,9 +0,0 @@
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

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

View File

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

View File

@ -1,5 +0,0 @@
package(default_visibility = ["//visibility:public"])
load("//rules_resf:defs.bzl", "migration_tar")
migration_tar()

View File

@ -1,65 +0,0 @@
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 = "apollopb_proto",
srcs = [
"advisory.proto",
"affected_product.proto",
"apollo.proto",
"build.proto",
"cve.proto",
"fix.proto",
"short_code.proto",
],
visibility = ["//visibility:public"],
deps = [
"@com_envoyproxy_protoc_gen_validate//validate:validate_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 = "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/apollo/pb",
proto = ":apollopb_proto",
visibility = ["//visibility:public"],
deps = [
"@com_envoyproxy_protoc_gen_validate//validate:validate_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 = ":apollopb_proto",
simple_operation_ids = True,
single_output = True,
)
openapi_generator(
name = "client_typescript",
generator = "typescript-fetch",
spec = ":openapi",
visibility = ["//visibility:public"],
)

View File

@ -1,112 +0,0 @@
syntax = "proto3";
package resf.apollo.v1;
import "google/protobuf/timestamp.proto";
import "google/protobuf/wrappers.proto";
import "apollo/proto/v1/cve.proto";
import "apollo/proto/v1/fix.proto";
option go_package = "peridot.resf.org/apollo/pb;apollopb";
message RPMs {
repeated string nvras = 1;
}
// Advisory
//
// Product advisory
message Advisory {
enum Type {
TYPE_UNKNOWN = 0;
TYPE_SECURITY = 1;
TYPE_BUGFIX = 2;
TYPE_ENHANCEMENT = 3;
}
// Type
//
// Type of advisory
Type type = 1;
// Short code
//
// Errata prefix or short code
// Example: RLBA, RLEA, RLSA
string short_code = 2;
// Name
//
// Full errata name
// Example: RLBA-2021:0001, RLSA-2021:0002
string name = 3;
// Synopsis
//
// Short description of advisory
string synopsis = 4;
enum Severity {
SEVERITY_UNKNOWN = 0;
SEVERITY_LOW = 1;
SEVERITY_MODERATE = 2;
SEVERITY_IMPORTANT = 3;
SEVERITY_CRITICAL = 4;
}
// Severity
//
// Severity of advisory. Used only for security advisories
Severity severity = 5;
// Topic
//
// Topic of advisory
// Example: An update for the go-toolset:rhel8 module is now available for Rocky Linux 8.
string topic = 6;
// Description
//
// Description of advisory. Contains information about changes and package.
string description = 7;
// Solution
//
// How to solve the advisory. Contains information about how to apply the advisory changes
google.protobuf.StringValue solution = 8;
// Affected products
//
// A list of affected products
repeated string affected_products = 9;
// Fixes
//
// A list of tickets from upstream bug trackers
repeated Fix fixes = 10;
// CVEs
//
// A list of CVEs assigned to this advisory
repeated CVE cves = 11;
// References
//
// General references used in this advisory
repeated string references = 12;
// Published at
//
// Timestamp the advisory is published at
google.protobuf.Timestamp published_at = 13;
// RPMs
//
// Affected RPMs
map<string, RPMs> rpms = 14;
// Reboot suggested
//
// Whether a system reboot should be suggested after applying this advisory
bool reboot_suggested = 15;
}

View File

@ -1,41 +0,0 @@
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

@ -1,161 +0,0 @@
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

@ -1,13 +0,0 @@
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;
}

View File

@ -1,28 +0,0 @@
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;
}

View File

@ -1,14 +0,0 @@
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

@ -1,29 +0,0 @@
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

@ -1,82 +0,0 @@
/*
* 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.
*/
insert into short_codes (code, mode)
values ('RL', 2);
insert into short_codes (code, mode)
values ('RK', 1);
--insert into products (id, name, current_full_version, redhat_major_version, short_code_code, archs, mirror_from_date, redhat_product_prefix, cpe)
--values (1, 'Rocky Linux 9', '9.0', 9, 'RL', array ['x86_64', 'aarch64', 'ppc64le', 's390x'], '2022-05-15'::timestamp, 'Rocky Linux', 'cpe:/o:redhat:enterprise_linux:9');
insert into products (id, name, current_full_version, redhat_major_version, short_code_code, archs, mirror_from_date, redhat_product_prefix, cpe, build_system, build_system_endpoint, koji_compose, koji_module_compose)
values (2, 'Rocky Linux 8', '8.6', 8, 'RL', array ['x86_64', 'aarch64'], '2022-05-15'::timestamp, 'Rocky Linux', 'cpe:/o:redhat:enterprise_linux:8', 'koji', 'https://koji.rockylinux.org/kojihub', 'dist-rocky8-compose', 'dist-rocky8-module-compose');
--insert into ignored_upstream_packages (product_id, package)
--values
-- (1, 'tfm-rubygem-unicode*'),
-- (1, 'katello-host-tools*'),
-- (1, 'openssl-ibmca*'),
-- (1, 'insights-client*'),
-- (1, 'tfm-rubygem-unicode-display_width*'),
-- (1, 'pulp*'),
-- (1, 'satellite*'),
-- (1, 'tfm-rubygem-unf_ext*'),
-- (1, 'foreman*'),
-- (1, 'kpatch*'),
-- (1, 'rhc-worker-playbook*');
insert into ignored_upstream_packages (product_id, package)
values
(2, 'tfm-rubygem-unicode*'),
(2, 'katello-host-tools*'),
(2, 'openssl-ibmca*'),
(2, 'insights-client*'),
(2, 'tfm-rubygem-unicode-display_width*'),
(2, 'pulp*'),
(2, 'satellite*'),
(2, 'tfm-rubygem-unf_ext*'),
(2, 'foreman*'),
(2, 'kpatch*'),
(2, 'rhc-worker-playbook*');
insert into reboot_suggested_packages (name)
values
('kernel'),
('kernel-PAE'),
('kernel-rt'),
('kernel-smp'),
('kernel-xen'),
('linux-firmware'),
('*-firmware-*'),
('dbus'),
('glibc'),
('hal'),
('systemd'),
('udev'),
('gnutls'),
('openssl-libs');

View File

@ -1,60 +0,0 @@
load("//rules_resf:defs.bzl", "RESFDEPLOY_OUTS_BASE", "container", "peridot_k8s", "resf_frontend")
package(default_visibility = ["//visibility:public"])
server_deps = ["//common/frontend_server"]
server_entrypoint = "server/index.mjs"
server_srcs = glob(["server/**/*.mjs"])
resf_frontend(
name = "apollo",
srcs = glob([
"src/**/*.tsx",
"src/**/*.ts",
]),
entrypoint = "apollo/ui/src/entrypoint.tsx",
index_html = "//rules_resf/internal/resf_bundle:index_no_mobile.hbs",
server_deps = server_deps,
server_entrypoint = server_entrypoint,
server_srcs = server_srcs,
tailwind_config = "//rules_resf/internal/resf_bundle:tailwind.config.nopreflight.js",
title = "Rocky Enterprise Software Foundation Product Errata",
deps = [
"//apollo/proto/v1:client_typescript",
"//common/mui",
"//common/ui",
"//tailwind:css",
"@npm//@chakra-ui/react",
"@npm//@chakra-ui/icons",
"@npm//@emotion/unitless",
"@npm//framer-motion",
"@npm//framesync",
"@npm//popmotion",
"@npm//style-value-types",
"@npm//await-to-js",
"@npm//react",
"@npm//react-dom",
"@npm//react-router",
"@npm//react-router-dom",
],
)
container(
base = "//bases/bazel/node",
files = [
":apollo.bundle",
],
frontend = True,
image_name = "apollo-frontend",
server_entrypoint = server_entrypoint,
server_files = server_srcs + server_deps,
)
peridot_k8s(
name = "apollo-frontend",
src = "deploy.jsonnet",
outs = RESFDEPLOY_OUTS_BASE,
deps = ["//ci"],
)

View File

@ -1,25 +0,0 @@
local resfdeploy = import 'ci/resfdeploy.jsonnet';
local kubernetes = import 'ci/kubernetes.jsonnet';
local frontend = import 'ci/frontend.jsonnet';
local tag = std.extVar('tag');
resfdeploy.new({
name: 'apollo-frontend',
backend: false,
migrate: false,
image: kubernetes.tag($.name),
tag: tag,
env: frontend.server_env,
ports: [
{
name: 'http',
containerPort: 8086,
protocol: 'TCP',
expose: true,
},
],
health: {
port: 8086,
},
})

View File

@ -1,61 +0,0 @@
/*
* 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.
*/
import server from '../../../common/frontend_server/index.mjs';
import {
svcNameHttp,
endpointHttp,
NS,
} from '../../../common/frontend_server/upstream.mjs';
export default async function run(webpackConfig) {
const devFrontendUrl = 'http://errata.pdot.localhost:9007';
const envPublicUrl = process.env['APOLLO_FRONTEND_HTTP_PUBLIC_URL'];
const frontendUrl = process.env['RESF_NS'] ? envPublicUrl : devFrontendUrl;
server({
baseURL: frontendUrl,
apis: {
'/api': {
prodApiUrl: endpointHttp(svcNameHttp('apollo'), NS('apollo')),
devApiUrl: `https://apollo-dev.internal.pdev.resf.localhost`,
},
},
port: 9007,
disableAuth: true,
webpackConfig,
}).then();
}
if (process.env.NODE_ENV === 'production') {
run().then();
}

View File

@ -1,39 +0,0 @@
/*
* 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.
*/
import * as apollo from 'bazel-bin/apollo/proto/v1/client_typescript';
export const api = new apollo.ApolloServiceApi(
new apollo.Configuration({
basePath: '/api', // Points to frontend API proxy
})
);

View File

@ -1,520 +0,0 @@
/*
* 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.
*/
import {
AddIcon,
ArrowLeftIcon,
ArrowRightIcon,
MinusIcon,
SearchIcon,
} from '@chakra-ui/icons';
import {
Alert,
AlertDescription,
AlertIcon,
AlertTitle,
Box,
ButtonGroup,
FormControl,
FormLabel,
HStack,
IconButton,
Input,
InputGroup,
InputLeftElement,
Link,
Select,
Spinner,
Stack,
Table,
TableColumnHeaderProps,
TableContainer,
Tbody,
Td,
Text,
Th,
Thead,
Tr,
useColorModeValue,
} from '@chakra-ui/react';
import {
severityToBadge,
severityToText,
typeToText,
} from 'apollo/ui/src/enumToText';
import {
ListAdvisoriesFiltersSeverityEnum,
ListAdvisoriesFiltersTypeEnum,
} from 'bazel-bin/apollo/proto/v1/client_typescript';
import {
V1Advisory,
V1AdvisoryType,
} from 'bazel-bin/apollo/proto/v1/client_typescript/models';
import { reqap } from 'common/ui/reqap';
import React, { useEffect, useState } from 'react';
import { Link as RouterLink } from 'react-router-dom';
import { api } from '../api';
import { COLOR_RESF_GREEN } from '../styles';
export const Overview = () => {
const inputBackground = useColorModeValue('white', undefined);
const tableBg = useColorModeValue('white', 'gray.800');
const pagerButtonScheme = useColorModeValue('blackAlpha', 'gray');
const linkBlue = useColorModeValue('blue.600', 'blue.300');
const linkPurple = useColorModeValue('purple.600', 'purple.300');
const [advisories, setAdvisories] = useState<V1Advisory[]>();
const [lastUpdated, setLastUpdated] = useState<Date>();
const [total, setTotal] = useState(0);
const [isLoading, setIsLoading] = useState(true);
const [isError, setIsError] = useState(false);
// Request State
const [page, setPage] = useState(0);
const [pageSize, setPageSize] = useState(25);
const [filtersKeyword, setFiltersKeyword] = useState<string>();
const [filterBefore, setFilterBefore] = useState<Date>();
const [filterAfter, setFilterAfter] = useState<Date>();
const [filterProduct, setFilterProduct] = useState<string>('');
const [filtersType, setFiltersType] =
useState<keyof typeof ListAdvisoriesFiltersTypeEnum>();
const [filtersSeverity, setFiltersSeverity] =
useState<keyof typeof ListAdvisoriesFiltersSeverityEnum>();
useEffect(() => {
const fetch = async () => {
setIsLoading(true);
const [err, res] = await reqap(() =>
api.listAdvisories({
page,
limit: pageSize,
filtersKeyword,
filtersBefore: filterBefore,
filtersAfter: filterAfter,
filtersProduct: filterProduct,
filtersSeverity: filtersSeverity
? ListAdvisoriesFiltersSeverityEnum[filtersSeverity]
: undefined,
filtersType: filtersType
? ListAdvisoriesFiltersTypeEnum[filtersType]
: undefined,
})
);
setIsLoading(false);
if (err || !res) {
setIsError(true);
setAdvisories(undefined);
return;
}
setIsError(false);
if (res) {
setAdvisories(res.advisories);
setLastUpdated(res.lastUpdated);
setTotal(parseInt(res.total || '0'));
}
};
const timer = setTimeout(() => fetch(), 500);
return () => clearTimeout(timer);
}, [
pageSize,
page,
filtersKeyword,
filterBefore,
filterAfter,
filtersSeverity,
filterProduct,
filtersType,
]);
// TODO: Figure out why sticky isn't sticking
const stickyProps: TableColumnHeaderProps = {
position: 'sticky',
top: '0px',
zIndex: '10',
scope: 'col',
};
const lastPage = total < pageSize ? 0 : Math.ceil(total / pageSize) - 1;
return (
<Box
w="100%"
h="100%"
display="flex"
flexDirection="column"
p={4}
alignItems="stretch"
>
<Stack
direction={{
sm: 'column',
lg: 'row',
}}
alignItems={{
sm: 'stretch',
lg: 'flex-end',
}}
>
<InputGroup>
<InputLeftElement>
<SearchIcon />
</InputLeftElement>
<Input
type="search"
aria-label="Keyword search"
placeholder="Keyword Search"
flexGrow={1}
width="200px"
variant="filled"
borderRadius="0"
backgroundColor={inputBackground}
onChange={(e) => setFiltersKeyword(e.target.value)}
/>
</InputGroup>
<HStack>
<FormControl width="180px" flexShrink={0} flexGrow={1}>
<FormLabel fontSize="sm">Type</FormLabel>
<Select
aria-label="Type"
placeholder="All"
variant="filled"
background={inputBackground}
borderRadius="0"
value={filtersType}
onChange={(e) => {
if (e.currentTarget.value !== 'Security') {
setFiltersSeverity(undefined);
}
setFiltersType(
e.currentTarget
.value as keyof typeof ListAdvisoriesFiltersTypeEnum
);
}}
>
{Object.keys(ListAdvisoriesFiltersTypeEnum)
.sort((a, b) => a.localeCompare(b))
.filter((a) => a !== 'Unknown')
.map((s) => (
<option key={s} value={s}>
{s}
</option>
))}
</Select>
</FormControl>
{filtersType === 'Security' && (
<FormControl width="180px" flexShrink={0} flexGrow={1}>
<FormLabel fontSize="sm">Severity</FormLabel>
<Select
aria-label="Severity"
placeholder="All"
variant="filled"
background={inputBackground}
borderRadius="0"
value={filtersSeverity}
onChange={(e) =>
setFiltersSeverity(
e.currentTarget
.value as keyof typeof ListAdvisoriesFiltersSeverityEnum
)
}
>
{Object.keys(ListAdvisoriesFiltersSeverityEnum)
.sort((a, b) => a.localeCompare(b))
.filter((a) => a !== 'Unknown')
.map((s) => (
<option key={s} value={s}>
{s}
</option>
))}
</Select>
</FormControl>
)}
<FormControl width="180px" flexShrink={0} flexGrow={1}>
<FormLabel fontSize="sm">Product</FormLabel>
<Select
aria-label="Product"
placeholder="All"
variant="filled"
background={inputBackground}
borderRadius="0"
value={filterProduct}
onChange={(e) => {
setFilterProduct(e.currentTarget.value as string);
}}
>
{['Rocky Linux 8', 'Rocky Linux 9'].map((s) => (
<option key={s} value={s}>{s}</option>
))}
</Select>
</FormControl>
</HStack>
<HStack>
<FormControl width="180px" flexShrink={0} flexGrow={1}>
<FormLabel fontSize="sm">From</FormLabel>
<Input
type="date"
variant="filled"
background={inputBackground}
borderRadius="0"
max={
filterBefore
? filterBefore.toLocaleDateString('en-ca')
: new Date().toLocaleDateString('en-ca')
}
value={filterAfter?.toLocaleDateString('en-ca') || ''}
onChange={(e) => {
const newVal = e.currentTarget.value;
console.log(newVal);
if (!newVal) {
setFilterAfter(undefined);
}
const asDate = new Date(newVal);
if (!(asDate instanceof Date) || isNaN(asDate.getTime())) {
// Check value parses as a date
return;
}
const [year, month, date] = newVal.split('-').map(Number);
setFilterAfter(new Date(year, month - 1, date));
}}
/>
</FormControl>
<FormControl width="180px" flexShrink={0} flexGrow={1}>
<FormLabel fontSize="sm">To</FormLabel>
<Input
type="date"
variant="filled"
background={inputBackground}
borderRadius="0"
min={filterAfter?.toLocaleDateString('en-ca')}
max={new Date().toLocaleDateString('en-ca')}
value={filterBefore?.toLocaleDateString('en-ca') || ''}
onChange={(e) => {
const newVal = e.currentTarget.value;
if (!newVal) {
setFilterBefore(undefined);
}
const asDate = new Date(newVal);
if (!(asDate instanceof Date) || isNaN(asDate.getTime())) {
// Check value parses as a date
return;
}
const [year, month, date] = newVal.split('-').map(Number);
setFilterBefore(
new Date(year, month - 1, date, 23, 59, 59, 59) // Set to 1ms prior to midnight to be inclusive of selected date
);
}}
/>
</FormControl>
</HStack>
</Stack>
<HStack my={4} justifyContent="space-between" flexWrap="wrap">
<Text fontStyle="italic" fontSize="xs">
Last updated {lastUpdated?.toLocaleString() || 'never'}
</Text>
<HStack>
<Text fontSize="xs">
Displaying {(page * pageSize + 1).toLocaleString()}-
{Math.min(total, page * pageSize + pageSize).toLocaleString()} of{' '}
{total.toLocaleString()}
</Text>
<ButtonGroup
size="xs"
isAttached
alignItems="stretch"
colorScheme={pagerButtonScheme}
>
<IconButton
aria-label="First Page"
icon={<ArrowLeftIcon fontSize="8px" />}
disabled={page <= 0}
onClick={() => setPage(0)}
/>
<IconButton
aria-label="Previous Page"
icon={<MinusIcon fontSize="8px" />}
disabled={page <= 0}
onClick={() => setPage((old) => old - 1)}
/>
<Text
fontSize="xs"
// borderTop="1px solid"
// borderBottom="1px solid"
borderColor="gray.200"
backgroundColor={tableBg}
lineHeight="24px"
px={2}
>
{(page + 1).toLocaleString()} / {(lastPage + 1).toLocaleString()}
</Text>
<IconButton
aria-label="Next Page"
icon={<AddIcon fontSize="8px" />}
disabled={page >= lastPage}
onClick={() => setPage((old) => old + 1)}
/>
<IconButton
aria-label="Last Page"
icon={<ArrowRightIcon fontSize="8px" />}
disabled={page >= lastPage}
onClick={() => setPage(lastPage)}
/>
</ButtonGroup>
</HStack>
</HStack>
{isLoading ? (
<Spinner
m="auto"
size="xl"
alignSelf="center"
color={COLOR_RESF_GREEN}
thickness="3px"
/>
) : isError ? (
<Alert
status="error"
m="auto"
flexDirection="column"
width="300px"
borderRadius="md"
>
<AlertIcon mr="0" />
<AlertTitle>Something has gone wrong</AlertTitle>
<AlertDescription>Failed to load errata</AlertDescription>
</Alert>
) : (
<Box backgroundColor={tableBg} boxShadow="base">
<TableContainer>
<Table size="sm" variant="striped">
<Thead>
<Tr>
<Th {...stickyProps} width="36px" />
<Th {...stickyProps}>Advisory</Th>
<Th {...stickyProps}>Synopsis</Th>
<Th {...stickyProps}>Type / Severity</Th>
<Th {...stickyProps}>Products</Th>
<Th {...stickyProps}>Issue Date</Th>
</Tr>
</Thead>
<Tbody>
{!advisories?.length && (
<Tr>
<Td colSpan={6} textAlign="center">
<Text>No rows found</Text>
</Td>
</Tr>
)}
{advisories?.map((a, idx) => (
<Tr key={a.name}>
<Td textAlign="center" pr={0}>
{severityToBadge(a.severity, a.type)}
</Td>
<Td>
<Link
as={RouterLink}
to={`/${a.name}`}
color={linkBlue}
_visited={{ color: linkPurple }}
>
{a.name}
</Link>
</Td>
<Td>
{a.synopsis?.replace(
/^(Critical|Important|Moderate|Low): /,
''
)}
</Td>
<Td>
{typeToText(a.type)}
{a.type === V1AdvisoryType.Security
? ` / ${severityToText(a.severity)}`
: ''}
</Td>
<Td>{a.affectedProducts?.join(', ')}</Td>
<Td>
{Intl.DateTimeFormat(undefined, {
day: '2-digit',
month: 'short',
year: 'numeric',
}).format(a.publishedAt)}
</Td>
</Tr>
))}
</Tbody>
</Table>
</TableContainer>
</Box>
)}
<HStack justifyContent="flex-end" mt={4}>
<Text as="label" htmlFor="row-count" fontSize="sm">
Rows per page:
</Text>
<Select
id="row-count"
name="row-count"
variant="filled"
backgroundColor={inputBackground}
width="100px"
size="sm"
value={pageSize}
onChange={(e) => {
setPage(0);
setPageSize(Number(e.currentTarget.value));
}}
>
{[10, 25, 50, 100].map((count) => (
<option key={count} value={count}>
{count.toLocaleString()}
</option>
))}
</Select>
</HStack>
</Box>
);
};

View File

@ -1,150 +0,0 @@
/*
* 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.
*/
import { MoonIcon, SunIcon } from '@chakra-ui/icons';
import {
Box,
HStack,
Text,
Link as ChakraLink,
useColorMode,
IconButton,
useColorModeValue,
DarkMode,
} from '@chakra-ui/react';
import { RESFLogo } from 'common/ui/RESFLogo';
import React from 'react';
import { Route, Switch } from 'react-router';
import { Link } from 'react-router-dom';
import { COLOR_RESF_BLUE, COLOR_RESF_GREEN } from '../styles';
import { Overview } from './Overview';
import { ShowErrata } from './ShowErrata';
export const Root = () => {
const { colorMode, toggleColorMode } = useColorMode();
const SwitchIcon = useColorModeValue(MoonIcon, SunIcon);
const bodyBg = useColorModeValue('gray.100', 'gray.900');
return (
<Box
display="flex"
width="100%"
minHeight="100vh"
flexDirection="column"
alignItems="stretch"
>
<Box
as="header"
background={`linear-gradient(to bottom right, ${COLOR_RESF_GREEN}, ${COLOR_RESF_BLUE})`}
display="flex"
flexDirection="row"
alignItems="center"
justifyContent="space-between"
py="1"
px={4}
>
<Link to="/" className="no-underline text-white">
<HStack flexGrow={1} height="90%" spacing="2">
<RESFLogo className="fill-current text-white" />
<Text
as="h1"
borderLeft="1px solid"
pl="2"
lineHeight="30px"
fontSize="xl"
fontWeight="300"
color="white"
whiteSpace="nowrap"
>
Product Errata
</Text>
</HStack>
</Link>
<DarkMode>
<IconButton
size="md"
fontSize="lg"
aria-label={`Switch to ${
colorMode === 'light' ? 'dark' : 'light'
} mode`}
variant="ghost"
onClick={toggleColorMode}
icon={<SwitchIcon />}
/>
</DarkMode>
</Box>
<Box as="main" flexGrow={1} overflow="auto" background={bodyBg}>
<Switch>
<Route path="/" exact component={Overview} />
<Route path="/:id" component={ShowErrata} />
</Switch>
</Box>
<Box
as="footer"
px="4"
// backgroundColor="#10859E"
background={`linear-gradient(to top left, ${COLOR_RESF_GREEN}, ${COLOR_RESF_BLUE})`}
color="white"
display="flex"
height="50px"
>
<ChakraLink
href="/api/v2/advisories:rss"
isExternal
display="flex"
alignItems="center"
my="auto"
>
<Box
as="svg"
viewBox="0 0 24 24"
width="18px"
height="18px"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
display="block"
mr={1.5}
>
<path d="M4 11a9 9 0 019 9M4 4a16 16 0 0116 16" />
<circle cx="5" cy="19" r="1" />
</Box>
<span>RSS</span>
</ChakraLink>
</Box>
</Box>
);
};

View File

@ -1,343 +0,0 @@
/*
* 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.
*/
import {
Alert,
AlertDescription,
AlertIcon,
AlertTitle,
Box,
Breadcrumb,
BreadcrumbItem,
BreadcrumbLink,
Heading,
HStack,
Link,
ListItem,
Spinner,
Tab,
TabList,
TabPanel,
TabPanels,
Tabs,
Text,
UnorderedList,
useColorModeValue,
VStack,
} from '@chakra-ui/react';
import {
severityToBadge,
severityToText,
typeToText,
} from 'apollo/ui/src/enumToText';
import {
V1Advisory,
V1AdvisoryType,
} from 'bazel-bin/apollo/proto/v1/client_typescript';
import { reqap } from 'common/ui/reqap';
import React, { useState } from 'react';
import { RouteComponentProps } from 'react-router';
import { Link as RouterLink } from 'react-router-dom';
import { api } from '../api';
import { COLOR_RESF_GREEN } from '../styles';
interface ShowErrataParams {
id: string;
}
export interface ShowErrataProps
extends RouteComponentProps<ShowErrataParams> {}
export const ShowErrata = (props: ShowErrataProps) => {
const id = props.match.params.id;
const cardBg = useColorModeValue('white', 'gray.800');
const sideBg = useColorModeValue('gray.100', 'gray.700');
const linkBlue = useColorModeValue('blue.600', 'blue.300');
const linkPurple = useColorModeValue('purple.600', 'purple.300');
const [errata, setErrata] = useState<V1Advisory>();
const [isLoading, setIsLoading] = useState(true);
const [isError, setIsError] = useState(false);
React.useEffect(() => {
const fetch = async () => {
setIsLoading(true);
const [err, res] = await reqap(() => api.getAdvisory({ id }));
setIsLoading(false);
if (err || !res) {
setIsError(true);
setErrata(undefined);
return;
}
setIsError(false);
setErrata(res.advisory);
};
fetch();
}, [id]);
return (
<Box
w="100%"
h="100%"
display="flex"
flexDirection="column"
p={4}
alignItems="stretch"
maxWidth="1300px"
m="auto"
>
<Breadcrumb mb={4}>
<BreadcrumbItem>
<BreadcrumbLink as={RouterLink} to="/">
Product Errata
</BreadcrumbLink>
</BreadcrumbItem>
<BreadcrumbItem>
<BreadcrumbLink isCurrentPage>{id}</BreadcrumbLink>
</BreadcrumbItem>
</Breadcrumb>
{isLoading ? (
<Spinner
m="auto"
size="xl"
alignSelf="center"
color={COLOR_RESF_GREEN}
thickness="3px"
/>
) : isError ? (
<Alert
status="error"
m="auto"
flexDirection="column"
width="300px"
borderRadius="md"
>
<AlertIcon mr="0" />
<AlertTitle>Something has gone wrong</AlertTitle>
<AlertDescription>Failed to load errata</AlertDescription>
</Alert>
) : (
errata && (
<>
<HStack
alignItems="center"
backgroundColor={cardBg}
py="2"
px="4"
spacing="6"
mb={2}
>
{severityToBadge(errata.severity, errata.type, 40)}
<VStack alignItems="stretch" spacing="0" flexGrow={1}>
<HStack justifyContent="space-between">
<Text fontSize="lg" fontWeight="bold">
{errata.name}
</Text>
</HStack>
<Text fontSize="sm">{errata.synopsis}</Text>
</VStack>
</HStack>
<Tabs backgroundColor={cardBg} p="2">
<TabList>
<Tab>Erratum</Tab>
<Tab>Affected Packages</Tab>
</TabList>
<Box
display="flex"
flexDir="row"
alignItems="stretch"
flexWrap="wrap"
justifyContent="space-between"
>
<TabPanels maxWidth="850px" px="2">
<TabPanel>
<Heading as="h2" size="md">
Topic
</Heading>
{errata.topic?.split('\n').map((p, i) => (
<Text key={i} mt={2}>
{p}
</Text>
))}
<Heading as="h2" size="md" mt={4}>
Description
</Heading>
{errata.description?.split('\n').map((p, i) => (
<Text key={i} mt={2}>
{p}
</Text>
))}
</TabPanel>
<TabPanel>
<VStack alignItems="flex-start" spacing="6">
{Object.keys(errata.rpms || {}).map((product) => (
<div key={product}>
<Heading as="h2" size="lg" mb={4} fontWeight="300">
{product}
</Heading>
<Heading as="h3" size="md" mt={2}>
SRPMs
</Heading>
<UnorderedList pl="4">
{errata.rpms?.[product]?.nvras
?.filter((x) => x.indexOf('.src.rpm') !== -1)
.map((x) => (
<ListItem key={x}>{x}</ListItem>
))}
</UnorderedList>
<Heading as="h3" size="md" mt={2}>
RPMs
</Heading>
<UnorderedList pl="4">
{errata.rpms?.[product]?.nvras
?.filter((x) => x.indexOf('.src.rpm') === -1)
.map((x) => (
<ListItem key={x}>{x}</ListItem>
))}
</UnorderedList>
</div>
))}
</VStack>
</TabPanel>
</TabPanels>
<VStack
py="4"
px="8"
alignItems="flex-start"
minWidth="300px"
spacing="5"
flexShrink={0}
backgroundColor={sideBg}
>
<Text>
<b>Issued:</b> {errata.publishedAt?.toLocaleDateString()}
</Text>
<Text>
<b>Type:</b> {typeToText(errata.type)}
</Text>
{errata.type === V1AdvisoryType.Security && (
<Text>
<b>Severity:</b> {severityToText(errata.severity)}
</Text>
)}
<Box>
<Text fontWeight="bold">
Affected Product
{(errata.affectedProducts?.length || 0) > 1 ? 's' : ''}
</Text>
<UnorderedList>
{errata.affectedProducts?.map((x, idx) => (
<ListItem key={idx}>{x}</ListItem>
))}
</UnorderedList>
</Box>
<Box>
<Text fontWeight="bold">Fixes</Text>
<UnorderedList>
{errata.fixes?.map((x, idx) => (
<ListItem key={idx}>
<Link
href={x.sourceLink}
isExternal
color={linkBlue}
_visited={{
color: linkPurple,
}}
>
{x.sourceBy} - {x.ticket}
</Link>
</ListItem>
))}
</UnorderedList>
</Box>
<Box>
<Text fontWeight="bold">CVEs</Text>
<UnorderedList>
{!!errata.cves?.length ? (
errata.cves?.map((x, idx) => {
let text = `${x.name}${
x.sourceBy !== '' && ` (Source: ${x.sourceBy})`
}`;
return (
<ListItem key={idx}>
{x.sourceLink === '' ? (
<span>{text}</span>
) : (
<Link
href={x.sourceLink}
isExternal
color={linkBlue}
_visited={{
color: linkPurple,
}}
>
{text}
</Link>
)}
</ListItem>
);
})
) : (
<ListItem>No CVEs</ListItem>
)}
</UnorderedList>
</Box>
<Box>
<Text fontWeight="bold">References</Text>
<UnorderedList>
{!!errata.references?.length ? (
errata.references?.map((x, idx) => (
<ListItem key={idx}>{x}</ListItem>
))
) : (
<ListItem>No references</ListItem>
)}
</UnorderedList>
</Box>
</VStack>
</Box>
</Tabs>
</>
)
)}
</Box>
);
};

View File

@ -1,61 +0,0 @@
/*
* 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.
*/
import 'tailwind/tailwind.css';
import { ChakraProvider, ColorModeScript } from '@chakra-ui/react';
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import { Root } from './components/Root';
import theme from './theme';
export const app = () => {
ReactDOM.render(
<>
<ColorModeScript initialColorMode={theme.config.initialColorMode} />
<BrowserRouter>
<ChakraProvider theme={theme}>
<Root />
</ChakraProvider>
</BrowserRouter>
</>,
document.getElementById('root')
);
};
app();
if (module.hot) {
module.hot.accept(app);
}

View File

@ -1,182 +0,0 @@
/*
* 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.
*/
import { Box, Tag, TagProps, Tooltip } from '@chakra-ui/react';
import {
AdvisorySeverity,
V1AdvisoryType,
} from 'bazel-bin/apollo/proto/v1/client_typescript';
import React from 'react';
export const severityToText = (severity?: AdvisorySeverity): string => {
switch (severity) {
case AdvisorySeverity.Critical:
return 'Critical';
case AdvisorySeverity.Important:
return 'Important';
case AdvisorySeverity.Moderate:
return 'Moderate';
case AdvisorySeverity.Low:
return 'Low';
default:
return 'None';
}
};
export const severityToBadge = (
severity: AdvisorySeverity | undefined,
type: V1AdvisoryType | undefined,
size: number = 20
): React.ReactNode => {
return (
<Tooltip
label={`${typeToText(type)}${
type === V1AdvisoryType.Security ? ` / ${severityToText(severity)}` : ''
}`}
placement="top-start"
hasArrow
>
{
{
[AdvisorySeverity.Critical]: (
<Box
as="svg"
version="1.1"
id="prefix__Layer_1"
xmlns="http://www.w3.org/2000/svg"
x="0"
y="0"
viewBox="0 0 24 24"
xmlSpace="preserve"
width={`${size}px`}
height={`${size}px`}
display="inline-block"
>
<g fill="#ED1C24">
<path d="M22.2 19.2l-8.8-16c-.2-.3-.5-.6-.8-.7-.3-.1-.7-.1-1.1 0-.3.1-.6.4-.8.7l-8.8 16c-.3.5-.2 1 0 1.5.3.5.8.7 1.3.8h17.7c.3 0 .5-.1.8-.2.2-.1.4-.3.5-.6.2-.4.2-1 0-1.5zm-18.8.6L12 4.3l8.6 15.5H3.4z" />
<path d="M12 15.7c-.2 0-.4.1-.6.2-.2.2-.2.4-.2.6v.8c0 .3.2.6.4.7.3.1.6.1.8 0s.4-.4.4-.7v-.8c0-.2-.1-.4-.2-.6-.2-.1-.4-.2-.6-.2zM11.2 9v5c0 .3.2.6.4.7.3.1.6.1.8 0 .3-.1.4-.4.4-.7V9c0-.3-.2-.6-.4-.7-.3-.1-.6-.1-.8 0s-.4.4-.4.7z" />
</g>
</Box>
),
[AdvisorySeverity.Important]: (
<Box
as="svg"
width={`${size}px`}
height={`${size}px`}
display="inline-block"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
>
<g fill="#F47B2A">
<path d="M22.2 19.2l-8.8-16c-.2-.3-.5-.6-.8-.7-.3-.1-.7-.1-1.1 0-.3.1-.6.4-.8.7l-8.8 16c-.3.5-.2 1 0 1.5.3.5.8.7 1.3.8h17.7c.3 0 .5-.1.8-.2.2-.1.4-.3.5-.6.2-.4.2-1 0-1.5zm-18.8.6L12 4.3l8.6 15.5H3.4z" />
<path d="M12 15.7c-.2 0-.4.1-.6.2-.2.2-.2.4-.2.6v.8c0 .3.2.6.4.7.3.1.6.1.8 0s.4-.4.4-.7v-.8c0-.2-.1-.4-.2-.6-.2-.1-.4-.2-.6-.2zM11.2 9v5c0 .3.2.6.4.7.3.1.6.1.8 0 .3-.1.4-.4.4-.7V9c0-.3-.2-.6-.4-.7-.3-.1-.6-.1-.8 0s-.4.4-.4.7z" />
</g>
</Box>
),
[AdvisorySeverity.Moderate]: (
<Box
as="svg"
width={`${size}px`}
height={`${size}px`}
display="inline-block"
version="1.1"
id="prefix__Layer_1"
xmlns="http://www.w3.org/2000/svg"
x="0"
y="0"
viewBox="0 0 24 24"
xmlSpace="preserve"
>
<path
fill="#ffc31a"
d="M22.2 19.2l-8.8-16c-.2-.3-.5-.6-.8-.7-.3-.1-.7-.1-1.1 0-.3.1-.6.4-.8.7l-8.8 16c-.3.5-.2 1 0 1.5.3.5.8.7 1.3.8h17.7c.3 0 .5-.1.8-.2.2-.1.4-.3.5-.6.2-.4.2-1 0-1.5zm-18.8.6L12 4.3l8.6 15.5H3.4z"
/>
<path
fill="#ffc31a"
d="M12 15.7c-.2 0-.4.1-.6.2-.2.2-.2.4-.2.6v.8c0 .3.2.6.4.7.3.1.6.1.8 0s.4-.4.4-.7v-.8c0-.2-.1-.4-.2-.6-.2-.1-.4-.2-.6-.2zM11.2 9v5c0 .3.2.6.4.7.3.1.6.1.8 0 .3-.1.4-.4.4-.7V9c0-.3-.2-.6-.4-.7-.3-.1-.6-.1-.8 0s-.4.4-.4.7z"
/>
</Box>
),
[AdvisorySeverity.Low]: (
<Box
as="svg"
width={`${size}px`}
height={`${size}px`}
display="inline-block"
version="1.1"
id="prefix__Layer_1"
xmlns="http://www.w3.org/2000/svg"
x="0"
y="0"
viewBox="0 0 24 24"
xmlSpace="preserve"
>
<g fill="#39B54A">
<path d="M22.2 19.2l-8.8-16c-.2-.3-.5-.6-.8-.7-.3-.1-.7-.1-1.1 0-.3.1-.6.4-.8.7l-8.8 16c-.3.5-.2 1 0 1.5.3.5.8.7 1.3.8h17.7c.3 0 .5-.1.8-.2.2-.1.4-.3.5-.6.2-.4.2-1 0-1.5zm-18.8.6L12 4.3l8.6 15.5H3.4z" />
<path d="M12 15.7c-.2 0-.4.1-.6.2-.2.2-.2.4-.2.6v.8c0 .3.2.6.4.7.3.1.6.1.8 0s.4-.4.4-.7v-.8c0-.2-.1-.4-.2-.6-.2-.1-.4-.2-.6-.2zM11.2 9v5c0 .3.2.6.4.7.3.1.6.1.8 0 .3-.1.4-.4.4-.7V9c0-.3-.2-.6-.4-.7-.3-.1-.6-.1-.8 0s-.4.4-.4.7z" />
</g>
</Box>
),
[AdvisorySeverity.Unknown]: (
<Box
as="svg"
width={`${size}px`}
height={`${size}px`}
display="inline-block"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
>
<g fill="#009444">
<path d="M22 5.6c0-.2 0-.3-.1-.4s-.2-.2-.4-.3L12.3 2h-.5L2.5 4.9c-.1 0-.3.1-.4.2-.1.2-.1.3-.1.5C2 6 1.6 15 6 19.5c.8.8 1.7 1.5 2.8 1.9 1 .4 2.2.6 3.3.6s2.2-.2 3.3-.6c1-.4 2-1.1 2.7-1.9C22.4 14.9 22 5.9 22 5.6zm-5 12.9c-1.3 1.4-3.1 2.1-5 2.1s-3.7-.7-5-2.1C3.6 15 3.4 8 3.4 6.1L12 3.4l8.6 2.7c0 1.9-.2 8.9-3.6 12.4z" />
<path d="M5.4 7c-.2 0-.3.1-.4.3-.1.1-.1.3-.1.4.1 2.1.6 7.2 3.1 9.8 1 1.1 2.4 1.7 3.9 1.6h.1c1.5 0 2.9-.6 3.9-1.6 2.5-2.6 3-7.7 3.2-9.8 0-.2 0-.3-.1-.4s-.2-.2-.4-.3l-6.4-2h-.4L5.4 7zm12.3 1.2c-.2 2.1-.7 6.3-2.7 8.3-.8.8-1.8 1.2-2.9 1.2H12c-1.1 0-2.1-.4-2.9-1.2-2-2.1-2.5-6.2-2.7-8.3L12 6.5l5.7 1.7z" />
<path d="M8.9 12.5l1.4 2.1c.1.2.3.3.6.3.2 0 .4-.1.5-.3l3.6-4.3c.2-.2.2-.5.1-.7-.1-.2-.3-.4-.5-.5-.3 0-.5.1-.7.2L11 13l-.9-1.3c-.1-.2-.3-.3-.5-.3s-.4 0-.6.1c-.2.1-.3.3-.3.5 0 .1.1.3.2.5z" />
</g>
</Box>
),
}[severity || AdvisorySeverity.Unknown]
}
</Tooltip>
);
};
export const typeToText = (type?: V1AdvisoryType): string => {
switch (type) {
case V1AdvisoryType.Bugfix:
return 'Bug Fix';
case V1AdvisoryType.Security:
return 'Security';
case V1AdvisoryType.Enhancement:
return 'Enhancement';
default:
return 'Unknown';
}
};

View File

@ -1,34 +0,0 @@
/*
* 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.
*/
export const COLOR_RESF_GREEN = '#10B981';
export const COLOR_RESF_BLUE = '#1054B9';

View File

@ -1,52 +0,0 @@
/*
* 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.
*/
import { extendTheme, type Theme, type ThemeConfig } from '@chakra-ui/react';
const config: ThemeConfig = {
initialColorMode: 'system',
};
const styles: Theme['styles'] = {
global: (props) => ({
':root': {
colorScheme: props.colorMode,
},
}),
};
const theme = extendTheme({
config,
styles,
});
export default theme;

View File

@ -1,15 +0,0 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "worker",
srcs = ["worker.go"],
importpath = "peridot.resf.org/apollo/worker",
visibility = ["//visibility:public"],
deps = [
"//apollo/db",
"//apollo/workflow",
"//vendor/github.com/sirupsen/logrus",
"//vendor/go.temporal.io/sdk/client",
"//vendor/go.temporal.io/sdk/worker",
],
)

View File

@ -1,82 +0,0 @@
// 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 worker
import (
"github.com/sirupsen/logrus"
"go.temporal.io/sdk/client"
"go.temporal.io/sdk/worker"
apollodb "peridot.resf.org/apollo/db"
"peridot.resf.org/apollo/workflow"
)
type Worker struct {
Client client.Client
TaskQueue string
WorkflowController *workflow.Controller
Worker worker.Worker
log *logrus.Logger
}
type NewWorkerInput struct {
Temporal client.Client
Database apollodb.Access
TaskQueue string
}
func NewWorker(input *NewWorkerInput, workflowOpts ...workflow.Option) (*Worker, error) {
log := logrus.New()
controller, err := workflow.NewController(&workflow.NewControllerInput{
Temporal: input.Temporal,
Database: input.Database,
MainQueue: input.TaskQueue,
}, workflowOpts...)
if err != nil {
return nil, err
}
return &Worker{
Client: input.Temporal,
TaskQueue: input.TaskQueue,
WorkflowController: controller,
Worker: worker.New(input.Temporal, input.TaskQueue, worker.Options{}),
log: log,
}, nil
}
func (w *Worker) Run() {
err := w.Worker.Run(worker.InterruptCh())
if err != nil {
w.log.Fatalf("could not run worker: %v", err)
}
}

View File

@ -1,59 +0,0 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
go_library(
name = "workflow",
srcs = [
"autocreate_advisory.go",
"collect_cve_data.go",
"common.go",
"downstream_check.go",
"poll_mirror_cve.go",
"poll_mirror_errata.go",
"update_cve_state.go",
"workflow.go",
],
importpath = "peridot.resf.org/apollo/workflow",
visibility = ["//visibility:public"],
deps = [
"//apollo/db",
"//apollo/proto/v1:pb",
"//apollo/rherrata",
"//apollo/rhsecurity",
"//apollo/rpmutils",
"//koji",
"//utils",
"//vendor/github.com/gobwas/glob",
"//vendor/github.com/jmoiron/sqlx/types",
"//vendor/github.com/pkg/errors",
"//vendor/github.com/sirupsen/logrus",
"//vendor/github.com/spf13/viper",
"//vendor/go.temporal.io/sdk/activity",
"//vendor/go.temporal.io/sdk/client",
"//vendor/go.temporal.io/sdk/workflow",
],
)
go_test(
name = "workflow_test",
srcs = [
"autocreate_advisory_test.go",
"downstream_check_test.go",
"poll_mirror_cve_test.go",
"poll_mirror_errata_test.go",
"update_cve_state_test.go",
"workflow_test.go",
],
data = glob(["testdata/**"]),
embed = [":workflow"],
deps = [
"//apollo/db",
"//apollo/db/mock",
"//apollo/proto/v1:pb",
"//apollo/rherrata",
"//apollo/rhsecurity",
"//apollo/rhsecuritymock",
"//koji",
"//vendor/github.com/stretchr/testify/require",
"//vendor/go.temporal.io/sdk/testsuite",
],
)

View File

@ -1,231 +0,0 @@
// 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 workflow
import (
"database/sql"
"fmt"
"github.com/sirupsen/logrus"
"go.temporal.io/sdk/workflow"
apollodb "peridot.resf.org/apollo/db"
"peridot.resf.org/apollo/rpmutils"
"strconv"
"strings"
"time"
)
func (c *Controller) AutoCreateAdvisoryActivity() error {
cves, err := c.db.GetAllCVEsFixedDownstream()
if err != nil {
c.log.Errorf("Could not get cves fixed downstream: %v", err)
return fmt.Errorf("could not get cves fixed downstream")
}
rebootSuggestedPackages, err := c.db.GetAllRebootSuggestedPackages()
if err != nil {
c.log.Errorf("Could not get reboot suggested packages: %v", err)
return fmt.Errorf("could not get reboot suggested packages")
}
for _, cve := range cves {
beginTx, err := c.db.Begin()
if err != nil {
logrus.Errorf("could not begin tx: %v", err)
continue
}
tx := c.db.UseTransaction(beginTx)
affectedProducts, err := tx.GetAllAffectedProductsByCVE(cve.ID)
if err != nil {
logrus.Errorf("Could not get affected products for %s: %v", cve.ID, err)
_ = beginTx.Rollback()
continue
}
var existingAdvisory *apollodb.Advisory
didSkip := false
for _, affectedProduct := range affectedProducts {
if !affectedProduct.Advisory.Valid {
continue
}
product, err := c.db.GetProductByID(affectedProduct.ProductID)
if err != nil {
c.log.Errorf("could not get product by id %d: %v", affectedProduct.ProductID, err)
return fmt.Errorf("could not get product by id %d", affectedProduct.ProductID)
}
advisorySplit := strings.Split(affectedProduct.Advisory.String, "-")
numYearSplit := strings.Split(advisorySplit[1], ":")
year, err := strconv.Atoi(numYearSplit[0])
if err != nil {
logrus.Errorf("invalid year %s", numYearSplit[0])
continue
}
num, err := strconv.Atoi(numYearSplit[1])
if err != nil {
logrus.Errorf("invalid num %s", numYearSplit[1])
continue
}
existingAdvisory, err = tx.GetAdvisoryByCodeAndYearAndNum(product.ShortCode, year, num)
if err != nil {
if err == sql.ErrNoRows {
errata, err := c.errata.GetErrata(affectedProduct.Advisory.String)
if err != nil {
logrus.Errorf("could not get errata from Red Hat: %v", err)
didSkip = true
break
}
for i, _ := range errata.Topic {
errata.Topic[i] = strings.Replace(errata.Topic[i], "Red Hat Enterprise Linux", product.RedHatProductPrefix.String, -1)
errata.Topic[i] = strings.Replace(errata.Topic[i], "Red Hat", c.vendor, -1)
}
for i, _ := range errata.Description {
errata.Description[i] = strings.Replace(errata.Description[i], "Red Hat Enterprise Linux", product.RedHatProductPrefix.String, -1)
errata.Description[i] = strings.Replace(errata.Description[i], "Red Hat", c.vendor, -1)
}
var packageName string
if !rpmutils.Module().MatchString(affectedProduct.Package) {
packageName = affectedProduct.Package
}
newAdvisory := &apollodb.Advisory{
Year: year,
Num: num,
Synopsis: errata.Synopsis,
Topic: strings.Join(errata.Topic, "\n"),
Severity: int(errata.Severity),
Type: int(errata.Type),
Description: strings.Join(errata.Description, "\n"),
RedHatIssuedAt: sql.NullTime{Valid: true, Time: errata.IssuedAt},
ShortCodeCode: product.ShortCode,
PublishedAt: sql.NullTime{},
}
if packageName != "" {
match, err := c.checkForRebootSuggestedPackage(rebootSuggestedPackages, packageName)
if err != nil {
c.log.Errorf("could not check for reboot suggested package: %v", err)
return fmt.Errorf("could not check for reboot suggested package")
}
if match {
newAdvisory.RebootSuggested = true
}
}
newAdvisory, err = tx.CreateAdvisory(newAdvisory)
if err != nil {
logrus.Errorf("Could not create new advisory: %v", err)
didSkip = true
break
}
existingAdvisory = newAdvisory
for _, fix := range errata.Fixes {
sourceLink := fmt.Sprintf("https://bugzilla.redhat.com/show_bug.cgi?id=%s", fix.BugzillaID)
id, err := tx.CreateFix(fix.BugzillaID, "Red Hat", sourceLink, fix.Description)
if err != nil {
logrus.Errorf("Could not create fix for BZ#%s", fix.BugzillaID)
didSkip = true
break
}
err = tx.AddAdvisoryFix(existingAdvisory.ID, id)
if err != nil {
logrus.Errorf("Could not add fix BZ#%s to advisory %d", fix.BugzillaID, existingAdvisory.ID)
didSkip = true
break
}
}
if didSkip {
break
}
for _, reference := range errata.References {
// Skip redhat.com references
if strings.Contains(reference, "redhat.com") {
continue
}
err := tx.CreateAdvisoryReference(existingAdvisory.ID, reference)
if err != nil {
logrus.Errorf("Could not reference %s", reference)
didSkip = true
break
}
}
if didSkip {
break
}
} else {
logrus.Errorf("Could not reach database to retrieve advisory: %v", err)
didSkip = true
break
}
}
if didSkip {
break
}
err = tx.AddAdvisoryCVE(existingAdvisory.ID, cve.ID)
if err != nil {
logrus.Errorf("Could not add %s to advisory %d", cve.ID, existingAdvisory.ID)
didSkip = true
break
}
}
if didSkip {
_ = beginTx.Rollback()
continue
}
err = beginTx.Commit()
if err != nil {
logrus.Errorf("Could not commit database transaction: %v", err)
continue
}
logrus.Infof("Created/updated advisory %s-%d:%d for %s", existingAdvisory.ShortCodeCode, existingAdvisory.Year, existingAdvisory.Num, cve.ID)
}
return nil
}
func (c *Controller) AutoCreateAdvisoryWorkflow(ctx workflow.Context) error {
activityCtx := workflow.WithActivityOptions(ctx, workflow.ActivityOptions{
ScheduleToStartTimeout: 5 * time.Minute,
StartToCloseTimeout: time.Hour,
})
return workflow.ExecuteActivity(activityCtx, c.AutoCreateAdvisoryActivity).Get(ctx, nil)
}

View File

@ -1,31 +0,0 @@
// 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 workflow

View File

@ -1,81 +0,0 @@
// 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 workflow
import (
"context"
"encoding/json"
"github.com/pkg/errors"
"go.temporal.io/sdk/workflow"
"strings"
"time"
)
func (c *Controller) CollectCVEDataActivity(ctx context.Context) error {
cves, err := c.db.GetAllCVEs()
if err != nil {
return errors.Wrap(err, "could not get cves")
}
// Go through each CVE and set CVE content by fetching from rhsecurity
for _, cve := range cves {
if cve.Content.Valid {
continue
}
if !strings.HasPrefix(cve.ID, "CVE") {
continue
}
cveRh, _, err := c.security.GetCveExecute(c.security.GetCve(ctx, cve.ID))
if err != nil {
return errors.Wrap(err, "could not get cve")
}
cveBytes, err := json.Marshal(cveRh)
if err != nil {
return errors.Wrap(err, "could not marshal cve")
}
err = c.db.SetCVEContent(cve.ID, cveBytes)
if err != nil {
return errors.Wrap(err, "could not set cve content")
}
}
return nil
}
func (c *Controller) CollectCVEDataWorkflow(ctx workflow.Context) error {
activityCtx := workflow.WithActivityOptions(ctx, workflow.ActivityOptions{
ScheduleToStartTimeout: 5 * time.Minute,
StartToCloseTimeout: 12 * time.Hour,
})
return workflow.ExecuteActivity(activityCtx, c.CollectCVEDataActivity).Get(ctx, nil)
}

View File

@ -1,31 +0,0 @@
// 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 workflow

View File

@ -1,203 +0,0 @@
// 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 workflow
import (
"context"
"fmt"
"github.com/sirupsen/logrus"
"go.temporal.io/sdk/activity"
"go.temporal.io/sdk/workflow"
apollodb "peridot.resf.org/apollo/db"
apollopb "peridot.resf.org/apollo/pb"
"peridot.resf.org/apollo/rpmutils"
"peridot.resf.org/utils"
"strings"
"time"
)
func (c *Controller) DownstreamCVECheckActivity(ctx context.Context) error {
go func() {
for {
activity.RecordHeartbeat(ctx)
time.Sleep(10 * time.Second)
}
}()
pendingProducts, err := c.db.GetPendingAffectedProducts()
if err != nil {
logrus.Errorf("could not get fixed cves: %v", err)
return fmt.Errorf("could not get fixed cves")
}
for _, affectedProduct := range pendingProducts {
if !affectedProduct.CveID.Valid {
continue
}
err = func() error {
willNotFixOnly := true
allFixed := true
switch affectedProduct.State {
case
int(apollopb.AffectedProduct_STATE_WILL_NOT_FIX_UPSTREAM),
int(apollopb.AffectedProduct_STATE_OUT_OF_SUPPORT_SCOPE):
return nil
case
int(apollopb.AffectedProduct_STATE_UNDER_INVESTIGATION_UPSTREAM),
int(apollopb.AffectedProduct_STATE_AFFECTED_UPSTREAM):
allFixed = false
willNotFixOnly = false
return nil
}
product, err := c.db.GetProductByID(affectedProduct.ProductID)
if err != nil {
logrus.Errorf("could not get product with id %d: %v", affectedProduct.ProductID, err)
return err
}
ignoredUpstreamPackages, err := c.db.GetAllIgnoredPackagesByProductID(product.ID)
if err != nil {
logrus.Errorf("could not get ignored packages: %v", err)
return err
}
beginTx, err := c.db.Begin()
if err != nil {
logrus.Errorf("could not begin transaction: %v", err)
return err
}
tx := c.db.UseTransaction(beginTx)
skipProduct := false
defer func(skipProduct *bool, affectedProduct apollodb.AffectedProduct) {
if *skipProduct {
logrus.Infof("%s: Skipping package for now", affectedProduct.Package)
_ = beginTx.Rollback()
}
}(&skipProduct, *affectedProduct)
cve, err := c.db.GetCVEByID(affectedProduct.CveID.String)
if err != nil {
return err
}
nvrOnly := strings.Replace(affectedProduct.Package, ":", "-", 1)
if rpmutils.Module().MatchString(nvrOnly) {
if !affectedProduct.Advisory.Valid {
skipProduct = true
}
redHatAdvisory, err := c.errata.GetErrata(affectedProduct.Advisory.String)
if err != nil {
logrus.Errorf("Could not get Red Hat Advisory: %v", err)
skipProduct = true
}
for _, arch := range product.Archs {
redHatProductName := affectedProductNameForArchAndVersion(arch, product.RedHatMajorVersion.Int32)
affected := redHatAdvisory.AffectedProducts[redHatProductName]
if affected == nil {
continue
}
srpms := affected.SRPMs
for _, srpm := range srpms {
status := c.checkKojiForBuild(tx, ignoredUpstreamPackages, srpm, affectedProduct, cve)
if status == apollopb.BuildStatus_BUILD_STATUS_SKIP {
skipProduct = true
break
} else if status == apollopb.BuildStatus_BUILD_STATUS_FIXED {
willNotFixOnly = false
} else if status == apollopb.BuildStatus_BUILD_STATUS_NOT_FIXED {
allFixed = false
willNotFixOnly = false
}
}
break
}
if skipProduct {
logrus.Errorf("%s has not been fixed for NVR %s", cve.ID, nvrOnly)
}
} else {
nvrOnly = rpmutils.Epoch().ReplaceAllString(affectedProduct.Package, "")
status := c.checkKojiForBuild(tx, ignoredUpstreamPackages, nvrOnly, affectedProduct, cve)
if status == apollopb.BuildStatus_BUILD_STATUS_SKIP {
skipProduct = true
} else if status == apollopb.BuildStatus_BUILD_STATUS_FIXED {
willNotFixOnly = false
} else if status == apollopb.BuildStatus_BUILD_STATUS_NOT_FIXED {
allFixed = false
willNotFixOnly = false
}
}
if !skipProduct {
newState := apollopb.AffectedProduct_STATE_FIXED_UPSTREAM
if allFixed {
newState = apollopb.AffectedProduct_STATE_FIXED_DOWNSTREAM
}
if willNotFixOnly {
newState = apollopb.AffectedProduct_STATE_WILL_NOT_FIX_UPSTREAM
}
err := tx.UpdateAffectedProductStateAndPackageAndAdvisory(affectedProduct.ID, int(newState), affectedProduct.Package, utils.NullStringToPointer(affectedProduct.Advisory))
if err != nil {
logrus.Errorf("Could not save new CVE state: %v", err)
return err
}
err = beginTx.Commit()
if err != nil {
logrus.Errorf("could not commit transaction: %v", err)
return err
}
logrus.Infof("%s is now set to %s", cve.ID, newState.String())
}
return nil
}()
if err != nil {
return err
}
}
return nil
}
func (c *Controller) DownstreamCVECheckWorkflow(ctx workflow.Context) error {
activityCtx := workflow.WithActivityOptions(ctx, workflow.ActivityOptions{
ScheduleToStartTimeout: 30 * time.Minute,
StartToCloseTimeout: 6 * time.Hour,
HeartbeatTimeout: 30 * time.Second,
})
return workflow.ExecuteActivity(activityCtx, c.DownstreamCVECheckActivity).Get(ctx, nil)
}

View File

@ -1,462 +0,0 @@
// 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 workflow
import (
"github.com/stretchr/testify/require"
"go.temporal.io/sdk/testsuite"
"io/ioutil"
apollopb "peridot.resf.org/apollo/pb"
"peridot.resf.org/apollo/rherrata"
"peridot.resf.org/koji"
"testing"
)
func getDownstreamCheckEnv() *testsuite.TestWorkflowEnvironment {
env := getPollRedHatErrataEnv()
env.RegisterActivity(controller.UpdateCVEStateActivity)
env.RegisterActivity(controller.DownstreamCVECheckActivity)
return env
}
func TestInstance_CheckIfCVEResolvedDownstream_RHBA20212593_NotFixedDownstream(t *testing.T) {
resetDb()
errataMock.Advisories.Response.Docs = []*rherrata.CompactErrata{
{
Name: "RHBA-2021:2593",
Description: "",
Synopsis: "",
Severity: "None",
Type: "Bug Fix",
AffectedPackages: []string{
"cmake-3.18.2-11.el8_4.src.rpm",
"cmake-3.18.2-11.el8_4.x86_64.rpm",
"cmake-data-3.18.2-11.el8_4.noarch.rpm",
"cmake-debuginfo-3.18.2-11.el8_4.i686.rpm",
"cmake-debuginfo-3.18.2-11.el8_4.x86_64.rpm",
"cmake-debugsource-3.18.2-11.el8_4.i686.rpm",
"cmake-debugsource-3.18.2-11.el8_4.x86_64.rpm",
"cmake-doc-3.18.2-11.el8_4.noarch.rpm",
"cmake-filesystem-3.18.2-11.el8_4.i686.rpm",
"cmake-filesystem-3.18.2-11.el8_4.x86_64.rpm",
"cmake-gui-3.18.2-11.el8_4.x86_64.rpm",
"cmake-gui-debuginfo-3.18.2-11.el8_4.i686.rpm",
"cmake-gui-debuginfo-3.18.2-11.el8_4.x86_64.rpm",
"cmake-rpm-macros-3.18.2-11.el8_4.noarch.rpm",
},
CVEs: []string{},
Fixes: []string{},
PublicationDate: "2021-06-29T00:00:00Z",
},
}
env := getDownstreamCheckEnv()
env.ExecuteWorkflow(controller.PollRedHatErrataWorkflow)
require.Nil(t, env.GetWorkflowError())
env = getDownstreamCheckEnv()
env.ExecuteWorkflow(controller.DownstreamCVECheckWorkflow)
require.Nil(t, env.GetWorkflowError())
affectedProducts, _ := controller.db.GetAllAffectedProductsByCVE("RHBA-2021:2593")
require.Len(t, affectedProducts, 1)
require.Equal(t, "cmake-3.18.2-11.el8_4", affectedProducts[0].Package)
require.Equal(t, int(apollopb.AffectedProduct_STATE_FIXED_UPSTREAM), affectedProducts[0].State)
}
func TestInstance_CheckIfCVEResolvedDownstream_RHBA20212593_FixedDownstream(t *testing.T) {
resetDb()
htmlFile, err := ioutil.ReadFile("testdata/RHBA-2021-2593.html")
require.Nil(t, err)
errataMock.HTMLResponses["RHBA-2021:2593"] = string(htmlFile[:])
errataMock.Advisories.Response.Docs = []*rherrata.CompactErrata{
{
Name: "RHBA-2021:2593",
Description: "",
Synopsis: "",
Severity: "None",
Type: "Bug Fix",
AffectedPackages: []string{
"cmake-3.18.2-11.el8_4.src.rpm",
"cmake-3.18.2-11.el8_4.x86_64.rpm",
"cmake-data-3.18.2-11.el8_4.noarch.rpm",
"cmake-debuginfo-3.18.2-11.el8_4.i686.rpm",
"cmake-debuginfo-3.18.2-11.el8_4.x86_64.rpm",
"cmake-debugsource-3.18.2-11.el8_4.i686.rpm",
"cmake-debugsource-3.18.2-11.el8_4.x86_64.rpm",
"cmake-doc-3.18.2-11.el8_4.noarch.rpm",
"cmake-filesystem-3.18.2-11.el8_4.i686.rpm",
"cmake-filesystem-3.18.2-11.el8_4.x86_64.rpm",
"cmake-gui-3.18.2-11.el8_4.x86_64.rpm",
"cmake-gui-debuginfo-3.18.2-11.el8_4.i686.rpm",
"cmake-gui-debuginfo-3.18.2-11.el8_4.x86_64.rpm",
"cmake-rpm-macros-3.18.2-11.el8_4.noarch.rpm",
},
CVEs: []string{},
Fixes: []string{},
PublicationDate: "2021-06-29T00:00:00Z",
},
}
env := getDownstreamCheckEnv()
env.ExecuteWorkflow(controller.PollRedHatErrataWorkflow)
require.Nil(t, env.GetWorkflowError())
env = getDownstreamCheckEnv()
env.ExecuteWorkflow(controller.UpdateCVEStateWorkflow)
require.Nil(t, env.GetWorkflowError())
kojiMock.Tagged = []*koji.Build{
{
BuildId: 10,
CompletionTime: "",
CompletionTs: 0,
CreationEventId: 0,
CreationTime: "",
CreationTs: 0,
Epoch: "",
Extra: &koji.ListBuildsExtra{
Source: &koji.ListBuildsExtraSource{
OriginalUrl: "git+https://git.rockylinux.org/staging/rpms/cmake.git?#aa313111d4efd7cc6c36d41cd9fc29874d1e0740",
},
},
Name: "cmake",
Nvr: "cmake-3.18.2-11.el8_4",
OwnerId: 0,
OwnerName: "distrobuild",
PackageId: 0,
PackageName: "cmake",
Release: "11.el8_4",
Source: "",
StartTime: "",
StartTs: 0,
State: 0,
TaskId: 0,
Version: "3.18.2",
VolumeId: 0,
VolumeName: "",
TagId: 0,
TagName: "",
},
}
kojiMock.RPMs = []*koji.RPM{
{
Arch: "src",
BuildId: 10,
Name: "cmake",
Nvr: "cmake-3.18.2-11.el8_4",
Release: "11.el8_4",
Version: "3.18.2",
},
{
Arch: "x86_64",
BuildId: 10,
Name: "cmake",
Nvr: "cmake-3.18.2-11.el8_4",
Release: "11.el8_4",
Version: "3.18.2",
},
{
Arch: "x86_64",
BuildId: 10,
Name: "cmake-gui",
Nvr: "cmake-gui-3.18.2-11.el8_4",
Release: "11.el8_4",
Version: "3.18.2",
},
{
Arch: "noarch",
BuildId: 10,
Name: "cmake-doc",
Nvr: "cmake-doc-3.18.2-11.el8_4",
Release: "11.el8_4",
Version: "3.18.2",
},
{
Arch: "noarch",
BuildId: 10,
Name: "cmake-rpm-macros",
Nvr: "cmake-rpm-macros-3.18.2-11.el8_4",
Release: "11.el8_4",
Version: "3.18.2",
},
{
Arch: "noarch",
BuildId: 10,
Name: "cmake-data",
Nvr: "cmake-data-3.18.2-11.el8_4",
Release: "11.el8_4",
Version: "3.18.2",
},
{
Arch: "i686",
BuildId: 10,
Name: "cmake-debuginfo",
Nvr: "cmake-debuginfo-3.18.2-11.el8_4",
Release: "11.el8_4",
Version: "3.18.2",
},
{
Arch: "x86_64",
BuildId: 10,
Name: "cmake-debuginfo",
Nvr: "cmake-debuginfo-3.18.2-11.el8_4",
Release: "11.el8_4",
Version: "3.18.2",
},
{
Arch: "i686",
BuildId: 10,
Name: "cmake-debugsource",
Nvr: "cmake-debugsource-3.18.2-11.el8_4",
Release: "11.el8_4",
Version: "3.18.2",
},
{
Arch: "x86_64",
BuildId: 10,
Name: "cmake-debugsource",
Nvr: "cmake-debugsource-3.18.2-11.el8_4",
Release: "11.el8_4",
Version: "3.18.2",
},
{
Arch: "i686",
BuildId: 10,
Name: "cmake-filesystem",
Nvr: "cmake-filesystem-3.18.2-11.el8_4",
Release: "11.el8_4",
Version: "3.18.2",
},
{
Arch: "x86_64",
BuildId: 10,
Name: "cmake-filesystem",
Nvr: "cmake-filesystem-3.18.2-11.el8_4",
Release: "11.el8_4",
Version: "3.18.2",
},
{
Arch: "i686",
BuildId: 10,
Name: "cmake-gui-debuginfo",
Nvr: "cmake-gui-debuginfo-3.18.2-11.el8_4",
Release: "11.el8_4",
Version: "3.18.2",
},
{
Arch: "x86_64",
BuildId: 10,
Name: "cmake-gui-debuginfo",
Nvr: "cmake-gui-debuginfo-3.18.2-11.el8_4",
Release: "11.el8_4",
Version: "3.18.2",
},
}
env = getDownstreamCheckEnv()
env.ExecuteWorkflow(controller.DownstreamCVECheckWorkflow)
require.Nil(t, env.GetWorkflowError())
affectedProducts, _ := controller.db.GetAllAffectedProductsByCVE("RHBA-2021:2593")
require.Len(t, affectedProducts, 1)
require.Equal(t, "cmake-3.18.2-11.el8_4", affectedProducts[0].Package)
require.Equal(t, int(apollopb.AffectedProduct_STATE_FIXED_DOWNSTREAM), affectedProducts[0].State)
require.Len(t, mockDb.BuildReferences, 14)
require.Equal(t, "10", mockDb.BuildReferences[0].KojiID.String)
}
/*func TestInstance_CheckIfCVEResolvedDownstream_RHSA20221642_FixedDownstream(t *testing.T) {
resetDb()
htmlFile, err := ioutil.ReadFile("testdata/RHSA-2022-1642.html")
require.Nil(t, err)
errataMock.HTMLResponses["RHSA-2022:1642"] = string(htmlFile[:])
errataMock.Advisories.Response.Docs = []*rherrata.CompactErrata{
{
Name: "RHSA-2022:1642",
Description: "",
Synopsis: "",
Severity: "Important",
Type: "Security",
AffectedPackages: []string{
"zlib-1.2.11-18.el8_5.src.rpm",
"zlib-1.2.11-18.el8_5.i686.rpm",
"zlib-1.2.11-18.el8_5.x86_64.rpm",
"zlib-debuginfo-1.2.11-18.el8_5.i686.rpm",
"zlib-debuginfo-1.2.11-18.el8_5.x86_64.rpm",
"zlib-debugsource-1.2.11-18.el8_5.i686.rpm",
"zlib-debugsource-1.2.11-18.el8_5.x86_64.rpm",
"zlib-devel-1.2.11-18.el8_5.i686.rpm",
"zlib-devel-1.2.11-18.el8_5.x86_64.rpm",
},
CVEs: []string{
"CVE-2018-25032",
},
Fixes: []string{},
PublicationDate: "2022-04-28T00:00:00Z",
},
}
env := getDownstreamCheckEnv()
env.ExecuteWorkflow(controller.PollRedHatErrataWorkflow)
require.Nil(t, env.GetWorkflowError())
kojiMock.Tagged = []*koji.Build{
{
BuildId: 10,
CompletionTime: "",
CompletionTs: 0,
CreationEventId: 0,
CreationTime: "",
CreationTs: 0,
Epoch: "",
Extra: &koji.ListBuildsExtra{
Source: &koji.ListBuildsExtraSource{
OriginalUrl: "git+https://git.rockylinux.org/staging/rpms/zlib.git?#cc63be52ed1ba4f25d2015fd014558a3e7e19b08",
},
},
Name: "zlib",
Nvr: "zlib-1.2.11-18.el8_5",
OwnerId: 0,
OwnerName: "distrobuild",
PackageId: 0,
PackageName: "zlib",
Release: "18.el8_5",
Source: "",
StartTime: "",
StartTs: 0,
State: 0,
TaskId: 0,
Version: "1.2.11",
VolumeId: 0,
VolumeName: "",
TagId: 0,
TagName: "",
},
}
kojiMock.RPMs = []*koji.RPM{
{
Arch: "src",
BuildId: 10,
Name: "zlib",
Nvr: "zlib-1.2.11-18.el8_5",
Release: "18.el8_5",
Version: "1.2.11",
},
{
Arch: "i686",
BuildId: 10,
Name: "zlib",
Nvr: "zlib-1.2.11-18.el8_5",
Release: "18.el8_5",
Version: "1.2.11",
},
{
Arch: "x86_64",
BuildId: 10,
Name: "zlib",
Nvr: "zlib-1.2.11-18.el8_5",
Release: "18.el8_5",
Version: "1.2.11",
},
{
Arch: "i686",
BuildId: 10,
Name: "zlib-debuginfo",
Nvr: "zlib-debuginfo-1.2.11-18.el8_5",
Release: "18.el8_5",
Version: "1.2.11",
},
{
Arch: "x86_64",
BuildId: 10,
Name: "zlib-debuginfo",
Nvr: "zlib-debuginfo-1.2.11-18.el8_5",
Release: "18.el8_5",
Version: "1.2.11",
},
{
Arch: "i686",
BuildId: 10,
Name: "zlib-debugsource",
Nvr: "zlib-debugsource-1.2.11-18.el8_5",
Release: "18.el8_5",
Version: "1.2.11",
},
{
Arch: "x86_64",
BuildId: 10,
Name: "zlib-debugsource",
Nvr: "zlib-debugsource-1.2.11-18.el8_5",
Release: "18.el8_5",
Version: "1.2.11",
},
{
Arch: "i686",
BuildId: 10,
Name: "zlib-devel",
Nvr: "zlib-devel-1.2.11-18.el8_5",
Release: "18.el8_5",
Version: "1.2.11",
},
{
Arch: "x86_64",
BuildId: 10,
Name: "zlib-devel",
Nvr: "zlib-devel-1.2.11-18.el8_5",
Release: "18.el8_5",
Version: "1.2.11",
},
}
env = getDownstreamCheckEnv()
env.ExecuteWorkflow(controller.DownstreamCVECheckWorkflow)
require.Nil(t, env.GetWorkflowError())
affectedProducts, _ := controller.db.GetAllAffectedProductsByCVE("RHSA-2022:1642")
require.Len(t, affectedProducts, 1)
require.Equal(t, "zlib-1.2.11-18.el8_5", affectedProducts[0].Package)
require.Equal(t, int(apollopb.AffectedProduct_STATE_FIXED_DOWNSTREAM), affectedProducts[0].State)
require.Len(t, mockDb.BuildReferences, 14)
require.Equal(t, "10", mockDb.BuildReferences[0].KojiID)
}*/

View File

@ -1,212 +0,0 @@
// 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 workflow
import (
"context"
"database/sql"
"encoding/json"
"fmt"
"github.com/jmoiron/sqlx/types"
"github.com/pkg/errors"
"go.temporal.io/sdk/activity"
"go.temporal.io/sdk/workflow"
apollodb "peridot.resf.org/apollo/db"
apollopb "peridot.resf.org/apollo/pb"
"peridot.resf.org/utils"
"strings"
"time"
)
type ShortCodesRes struct {
ShortCodes []*apollodb.ShortCode `json:"short_codes"`
}
func (c *Controller) pollCVEProcessProduct(ctx context.Context, product *apollodb.Product, shortCode *apollodb.ShortCode) error {
// Skip if the product doesn't define a valid Red Hat version
if !product.RedHatMajorVersion.Valid {
return nil
}
// Skip if product doesn't have correct Red Hat prefix
if !strings.HasPrefix(product.Name, product.RedHatProductPrefix.String) {
return nil
}
var lastSync *time.Time
mirrorState, err := c.db.GetMirrorState(shortCode.Code)
if err != nil {
if err != sql.ErrNoRows {
c.log.Errorf("could not get last sync for code %s: %v", shortCode.Code, err)
// The cron will retry this
return nil
}
} else {
if mirrorState != nil && mirrorState.LastSync.Valid {
lastSync = &mirrorState.LastSync.Time
}
}
if lastSync == nil {
now := time.Now()
if product.MirrorFromDate.Valid {
now = product.MirrorFromDate.Time
}
lastSync = &now
}
req := c.security.GetCves(ctx)
req = req.Product(productName(product.RedHatMajorVersion.Int32))
if lastSync != nil {
req = req.After(lastSync.Format("2006-01-02"))
}
page := 1
for {
reqNew := req.Page(float32(page))
cves, _, err := c.security.GetCvesExecute(reqNew)
if err != nil {
c.log.Errorf("could not get cves: %v", err)
return fmt.Errorf("could not get cves")
}
if len(cves) == 0 {
break
}
for _, cve := range cves {
_, err := c.db.GetCVEByID(cve.CVE)
if err == nil {
continue
}
if err != sql.ErrNoRows {
c.log.Errorf("an unknown error occurred: %v", err)
return fmt.Errorf("an unknown error occurred")
}
cveRh, _, err := c.security.GetCveExecute(c.security.GetCve(ctx, cve.CVE))
if err != nil {
return errors.Wrap(err, "could not get cve")
}
cveBytes, err := json.Marshal(cveRh)
if err != nil {
return fmt.Errorf("could not marshal cve: %v", err)
}
sourceBy := "Red Hat"
_, err = c.db.CreateCVE(cve.CVE, shortCode.Code, &sourceBy, &cve.ResourceUrl, types.NullJSONText{Valid: true, JSONText: cveBytes})
if err != nil {
c.log.Errorf("could not create cve: %v", err)
return fmt.Errorf("could not create cve")
}
c.log.Infof("Added %s to %s with state NewFromUpstream", cve.CVE, shortCode.Code)
}
page++
}
err = c.db.UpdateMirrorState(shortCode.Code, utils.Pointer[time.Time](time.Now()))
if err != nil {
c.log.Errorf("could not update mirroring state: %v", err)
}
return nil
}
func (c *Controller) PollCVEProcessShortCodeActivity(ctx context.Context, shortCode *apollodb.ShortCode) error {
go func() {
for {
activity.RecordHeartbeat(ctx)
time.Sleep(10 * time.Second)
}
}()
if int32(shortCode.Mode) != int32(apollopb.ShortCode_MODE_MIRROR) {
// This is not a mirrored short code, continue
return nil
}
allProducts, err := c.db.GetProductsByShortCode(shortCode.Code)
if err != nil {
c.log.Errorf("could not get all products for code %s: %v", shortCode.Code, err)
// Returning nil since the cron will retry this
// We can set up an alert on the Grafana side to alert us
// if this happens too often
return nil
}
for _, product := range allProducts {
err := c.pollCVEProcessProduct(ctx, product, shortCode)
if err != nil {
return err
}
}
return nil
}
func (c *Controller) GetAllShortCodesActivity() (*ShortCodesRes, error) {
s, err := c.db.GetAllShortCodes()
if err != nil {
return nil, err
}
return &ShortCodesRes{
ShortCodes: s,
}, nil
}
func (c *Controller) PollRedHatCVEsWorkflow(ctx workflow.Context) error {
shortCodeCtx := workflow.WithActivityOptions(ctx, workflow.ActivityOptions{
ScheduleToStartTimeout: time.Minute,
StartToCloseTimeout: time.Minute,
})
var shortCodeRes ShortCodesRes
err := workflow.ExecuteActivity(shortCodeCtx, c.GetAllShortCodesActivity).Get(ctx, &shortCodeRes)
if err != nil {
return err
}
var futures []workflow.Future
for _, shortCode := range shortCodeRes.ShortCodes {
activityCtx := workflow.WithActivityOptions(ctx, workflow.ActivityOptions{
ScheduleToStartTimeout: 5 * time.Minute,
StartToCloseTimeout: 12 * time.Hour,
HeartbeatTimeout: 30 * time.Second,
})
futures = append(futures, workflow.ExecuteActivity(activityCtx, c.PollCVEProcessShortCodeActivity, shortCode))
}
for _, future := range futures {
err := future.Get(ctx, nil)
if err != nil {
return err
}
}
return nil
}

View File

@ -1,118 +0,0 @@
// 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 workflow
import (
"github.com/stretchr/testify/require"
"go.temporal.io/sdk/testsuite"
"peridot.resf.org/apollo/rhsecurity"
"testing"
)
func getPollRedHatCVEsEnv() *testsuite.TestWorkflowEnvironment {
env := testWfSuite.NewTestWorkflowEnvironment()
env.RegisterActivity(controller.GetAllShortCodesActivity)
env.RegisterActivity(controller.PollCVEProcessShortCodeActivity)
return env
}
func TestInstance_PollRedHatForNewCVEs_AddNewCVE(t *testing.T) {
resetDb()
securityMock.Cves[1] = []*rhsecurity.CVE{
{
CVE: "CVE-2021-3602",
Severity: "moderate",
PublicDate: "2021-07-15T14:00:00Z",
Advisories: []string{},
Bugzilla: "1969264",
BugzillaDescription: "CVE-2021-3602 buildah: Host environment variables leaked in build container when using chroot isolation",
CvssScore: nil,
CvssScoringVector: nil,
CWE: "CWE-200",
AffectedPackages: nil,
ResourceUrl: "https://access.redhat.com/hydra/rest/securitydata/cve/CVE-2021-3602.json",
Cvss3ScoringVector: "CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:C/C:H/I:N/A:N",
Cvss3Score: "5.6",
},
}
securityMock.ActiveCVE = &rhsecurity.CVEDetailed{}
require.Nil(t, readTestDataJson("testdata/CVE-2021-3602.json", securityMock.ActiveCVE))
env := getPollRedHatCVEsEnv()
env.ExecuteWorkflow(controller.PollRedHatCVEsWorkflow)
require.Nil(t, env.GetWorkflowError())
cves, _ := controller.db.GetAllUnresolvedCVEs()
require.Len(t, cves, 1)
require.Equal(t, "CVE-2021-3602", cves[0].ID)
}
func TestPollRedHatForNewCVEs_SkipExistingCVE(t *testing.T) {
resetDb()
securityMock.Cves[1] = []*rhsecurity.CVE{
{
CVE: "CVE-2021-3602",
Severity: "moderate",
PublicDate: "2021-07-15T14:00:00Z",
Advisories: []string{},
Bugzilla: "1969264",
BugzillaDescription: "CVE-2021-3602 buildah: Host environment variables leaked in build container when using chroot isolation",
CvssScore: nil,
CvssScoringVector: nil,
CWE: "CWE-200",
AffectedPackages: nil,
ResourceUrl: "https://access.redhat.com/hydra/rest/securitydata/cve/CVE-2021-3602.json",
Cvss3ScoringVector: "CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:C/C:H/I:N/A:N",
Cvss3Score: "5.6",
},
}
securityMock.ActiveCVE = &rhsecurity.CVEDetailed{}
require.Nil(t, readTestDataJson("testdata/CVE-2021-3602.json", securityMock.ActiveCVE))
env := getPollRedHatCVEsEnv()
env.ExecuteWorkflow(controller.PollRedHatCVEsWorkflow)
require.Nil(t, env.GetWorkflowError())
cves, _ := controller.db.GetAllUnresolvedCVEs()
require.Len(t, cves, 1)
require.Equal(t, "CVE-2021-3602", cves[0].ID)
env = getPollRedHatCVEsEnv()
env.ExecuteWorkflow(controller.PollRedHatCVEsWorkflow)
require.Nil(t, env.GetWorkflowError())
cves, _ = controller.db.GetAllUnresolvedCVEs()
require.Len(t, cves, 1)
require.Equal(t, "CVE-2021-3602", cves[0].ID)
}

View File

@ -1,304 +0,0 @@
// 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 workflow
import (
"context"
"database/sql"
"encoding/json"
"fmt"
"github.com/jmoiron/sqlx/types"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"go.temporal.io/sdk/activity"
"go.temporal.io/sdk/workflow"
apollodb "peridot.resf.org/apollo/db"
apollopb "peridot.resf.org/apollo/pb"
"peridot.resf.org/apollo/rpmutils"
"peridot.resf.org/utils"
"strconv"
"strings"
"time"
)
func (c *Controller) processErrataShortCodeProduct(shortCode *apollodb.ShortCode, product *apollodb.Product) error {
if !product.RedHatMajorVersion.Valid {
return nil
}
if !strings.HasPrefix(product.Name, product.RedHatProductPrefix.String) {
return nil
}
ignoredUpstreamPackages, err := c.db.GetAllIgnoredPackagesByProductID(product.ID)
if err != nil {
logrus.Errorf("could not get ignored packages: %v", err)
return fmt.Errorf("could not get ignored packages")
}
var lastSync *time.Time
mirrorState, err := c.db.GetMirrorState(shortCode.Code)
if err == nil {
if mirrorState.ErrataAfter.Valid {
lastSync = &mirrorState.ErrataAfter.Time
}
}
advisories, err := c.errata.GetAdvisories(product.CurrentFullVersion, lastSync)
if err != nil {
logrus.Errorf("Could not get Red Hat Advisories: %v", err)
return fmt.Errorf("could not get Red Hat Advisories")
}
var newLastSync *time.Time
parentBeginTx, err := c.db.Begin()
if err != nil {
return fmt.Errorf("could not begin transaction: %v", err)
}
parentTx := c.db.UseTransaction(parentBeginTx)
rollbackParent := true
defer func() {
if rollbackParent {
_ = parentBeginTx.Rollback()
}
}()
for _, advisory := range advisories {
if newLastSync == nil {
parsedTime, err := time.Parse(time.RFC3339, advisory.PublicationDate)
if err == nil {
newLastSync = &parsedTime
_ = parentTx.UpdateMirrorStateErrata(shortCode.Code, newLastSync)
}
}
advisoryId := rpmutils.AdvisoryId().FindStringSubmatch(advisory.Name)
if len(advisoryId) < 5 {
logrus.Errorf("Invalid advisory %s", advisory.Name)
return nil
}
code := advisoryId[1]
year, err := strconv.Atoi(advisoryId[3])
if err != nil {
logrus.Errorf("Invalid advisory %s", advisory.Name)
return nil
}
num, err := strconv.Atoi(advisoryId[4])
if err != nil {
logrus.Errorf("Invalid advisory %s", advisory.Name)
return nil
}
beginTx, err := c.db.Begin()
if err != nil {
logrus.Errorf("Could not begin tx: %v", err)
return fmt.Errorf("could not begin tx")
}
tx := c.db.UseTransaction(beginTx)
_, err = tx.GetAdvisoryByCodeAndYearAndNum(code, year, num)
if err != nil {
if err == sql.ErrNoRows {
// If security then just add CVEs, the rest should be automatic
if strings.HasPrefix(advisory.Name, "RHSA") {
for _, cve := range advisory.CVEs {
_, err := tx.GetCVEByID(cve)
if err == nil {
continue
}
if err != sql.ErrNoRows {
logrus.Errorf("an unknown error occurred: %v", err)
_ = beginTx.Rollback()
return fmt.Errorf("an unknown error occurred")
}
sourceBy := "Red Hat"
resourceUrl := fmt.Sprintf("https://access.redhat.com/hydra/rest/securitydata/cve/%s.json", cve)
cveRh, _, err := c.security.GetCveExecute(c.security.GetCve(context.TODO(), cve))
if err != nil {
return errors.Wrap(err, "could not get cve")
}
cveBytes, err := json.Marshal(cveRh)
if err != nil {
return fmt.Errorf("could not marshal cve: %v", err)
}
_, err = tx.CreateCVE(cve, shortCode.Code, &sourceBy, &resourceUrl, types.NullJSONText{Valid: true, JSONText: cveBytes})
if err != nil {
logrus.Errorf("could not create cve: %v", err)
_ = beginTx.Rollback()
return fmt.Errorf("could not create cve")
}
logrus.Infof("Added %s to %s (%s)", cve, shortCode.Code, advisory.Name)
}
} else if strings.HasPrefix(advisory.Name, "RHBA") || strings.HasPrefix(advisory.Name, "RHEA") {
_, err := tx.GetAffectedProductByAdvisory(advisory.Name)
if err != nil {
if err == sql.ErrNoRows {
_, err := tx.GetCVEByID(advisory.Name)
if err == nil {
continue
}
if err != sql.ErrNoRows {
logrus.Errorf("an unknown error occurred: %v", err)
_ = beginTx.Rollback()
return fmt.Errorf("an unknown error occurred")
}
sourceBy := "Red Hat"
resourceUrl := fmt.Sprintf("https://access.redhat.com/errata/%s", advisory.Name)
_, err = tx.CreateCVE(advisory.Name, product.ShortCode, &sourceBy, &resourceUrl, types.NullJSONText{})
if err != nil {
_ = beginTx.Rollback()
return fmt.Errorf("could not create cve: %v", err)
}
for _, srpm := range advisory.AffectedPackages {
if !strings.Contains(srpm, ".src.rpm") {
continue
}
pkg := strings.Replace(srpm, ".src.rpm", "", 1)
nvr := rpmutils.NVR().FindStringSubmatch(pkg)
var packageName string
if len(nvr) >= 2 {
packageName = nvr[1]
} else {
packageName = pkg
}
if utils.StrContains(packageName, ignoredUpstreamPackages) {
continue
}
dist := fmt.Sprintf("el%d", product.RedHatMajorVersion.Int32)
if !strings.Contains(pkg, dist) {
continue
}
if strings.Contains(pkg, dist+"sat") {
continue
}
_, err := tx.CreateAffectedProduct(product.ID, advisory.Name, int(apollopb.AffectedProduct_STATE_FIXED_UPSTREAM), product.CurrentFullVersion, pkg, &advisory.Name)
if err != nil {
_ = beginTx.Rollback()
return fmt.Errorf("could not create affected product for srpm: %v", err)
}
}
logrus.Infof("Added %s to %s", advisory.Name, shortCode.Code)
} else {
_ = beginTx.Rollback()
return fmt.Errorf("Could not get affected product by advisory: %v", err)
}
}
}
} else {
_ = beginTx.Rollback()
logrus.Errorf("Could not fetch advisory: %v", err)
return err
}
}
err = beginTx.Commit()
if err != nil {
logrus.Errorf("Could not commit new advisory tx: %v", err)
return err
}
}
rollbackParent = false
err = parentBeginTx.Commit()
if err != nil {
logrus.Errorf("Could not commit parent tx: %v", err)
return err
}
return nil
}
func (c *Controller) ProcessRedHatErrataShortCodeActivity(ctx context.Context, shortCode *apollodb.ShortCode) error {
go func() {
for {
activity.RecordHeartbeat(ctx)
time.Sleep(10 * time.Second)
}
}()
if int32(shortCode.Mode) != int32(apollopb.ShortCode_MODE_MIRROR) {
// This is not a mirrored short code, continue
return nil
}
allProducts, err := c.db.GetProductsByShortCode(shortCode.Code)
if err != nil {
logrus.Errorf("could not get all products for code %s: %v", shortCode.Code, err)
return fmt.Errorf("could not get all products for code %s", shortCode.Code)
}
for _, product := range allProducts {
err := c.processErrataShortCodeProduct(shortCode, product)
if err != nil {
return err
}
}
return nil
}
func (c *Controller) PollRedHatErrataWorkflow(ctx workflow.Context) error {
shortCodeCtx := workflow.WithActivityOptions(ctx, workflow.ActivityOptions{
ScheduleToStartTimeout: time.Minute,
StartToCloseTimeout: time.Minute,
})
var shortCodeRes ShortCodesRes
err := workflow.ExecuteActivity(shortCodeCtx, c.GetAllShortCodesActivity).Get(ctx, &shortCodeRes)
if err != nil {
return err
}
var futures []workflow.Future
for _, shortCode := range shortCodeRes.ShortCodes {
activityCtx := workflow.WithActivityOptions(ctx, workflow.ActivityOptions{
ScheduleToStartTimeout: 5 * time.Minute,
StartToCloseTimeout: 12 * time.Hour,
HeartbeatTimeout: 30 * time.Second,
})
futures = append(futures, workflow.ExecuteActivity(activityCtx, c.ProcessRedHatErrataShortCodeActivity, shortCode))
}
for _, future := range futures {
err := future.Get(ctx, nil)
if err != nil {
return err
}
}
return nil
}

View File

@ -1,141 +0,0 @@
// 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 workflow
import (
"github.com/stretchr/testify/require"
"go.temporal.io/sdk/testsuite"
apollopb "peridot.resf.org/apollo/pb"
"peridot.resf.org/apollo/rherrata"
"testing"
)
func getPollRedHatErrataEnv() *testsuite.TestWorkflowEnvironment {
env := testWfSuite.NewTestWorkflowEnvironment()
env.RegisterActivity(controller.GetAllShortCodesActivity)
env.RegisterActivity(controller.ProcessRedHatErrataShortCodeActivity)
return env
}
func TestInstance_ScanRedHatErrata_RHSA20212595_Security_CVE(t *testing.T) {
resetDb()
errataMock.Advisories.Response.Docs = []*rherrata.CompactErrata{
{
Name: "RHSA-2021:2595",
Description: "",
Synopsis: "",
Severity: "Moderate",
Type: "Security",
AffectedPackages: []string{
"389-ds-base-1.4.3.16-16.module+el8.4.0+11446+fc96bc48.src.rpm",
"389-ds-base-1.4.3.16-16.module+el8.4.0+11446+fc96bc48.x86_64.rpm",
"389-ds-base-debuginfo-1.4.3.16-16.module+el8.4.0+11446+fc96bc48.x86_64.rpm",
"389-ds-base-debugsource-1.4.3.16-16.module+el8.4.0+11446+fc96bc48.x86_64.rpm",
"389-ds-base-devel-1.4.3.16-16.module+el8.4.0+11446+fc96bc48.x86_64.rpm",
"389-ds-base-legacy-tools-1.4.3.16-16.module+el8.4.0+11446+fc96bc48.x86_64.rpm",
"389-ds-base-legacy-tools-debuginfo-1.4.3.16-16.module+el8.4.0+11446+fc96bc48.x86_64.rpm",
"389-ds-base-libs-1.4.3.16-16.module+el8.4.0+11446+fc96bc48.x86_64.rpm",
"389-ds-base-libs-debuginfo-1.4.3.16-16.module+el8.4.0+11446+fc96bc48.x86_64.rpm",
"389-ds-base-snmp-1.4.3.16-16.module+el8.4.0+11446+fc96bc48.x86_64.rpm",
"389-ds-base-snmp-debuginfo-1.4.3.16-16.module+el8.4.0+11446+fc96bc48.x86_64.rpm",
"python3-lib389-1.4.3.16-16.module+el8.4.0+11446+fc96bc48.noarch.rpm",
},
CVEs: []string{
"CVE-2021-3514",
},
Fixes: []string{
"1952907",
"1960720",
"1968588",
"1970791",
"1972721",
"1972738",
},
PublicationDate: "2021-06-29T00:00:00Z",
},
}
env := getPollRedHatErrataEnv()
env.ExecuteWorkflow(controller.PollRedHatErrataWorkflow)
require.Nil(t, env.GetWorkflowError())
cves, _ := controller.db.GetAllUnresolvedCVEs()
require.Len(t, cves, 1)
require.Equal(t, "CVE-2021-3514", cves[0].ID)
}
func TestInstance_ScanRedHatErrata_BugFix_Erratum(t *testing.T) {
resetDb()
errataMock.Advisories.Response.Docs = []*rherrata.CompactErrata{
{
Name: "RHBA-2021:2593",
Description: "",
Synopsis: "",
Severity: "None",
Type: "Bug Fix",
AffectedPackages: []string{
"cmake-3.18.2-11.el8_4.src.rpm",
"cmake-3.18.2-11.el8_4.x86_64.rpm",
"cmake-data-3.18.2-11.el8_4.noarch.rpm",
"cmake-debuginfo-3.18.2-11.el8_4.i686.rpm",
"cmake-debuginfo-3.18.2-11.el8_4.x86_64.rpm",
"cmake-debugsource-3.18.2-11.el8_4.i686.rpm",
"cmake-debugsource-3.18.2-11.el8_4.x86_64.rpm",
"cmake-doc-3.18.2-11.el8_4.noarch.rpm",
"cmake-filesystem-3.18.2-11.el8_4.i686.rpm",
"cmake-filesystem-3.18.2-11.el8_4.x86_64.rpm",
"cmake-gui-3.18.2-11.el8_4.x86_64.rpm",
"cmake-gui-debuginfo-3.18.2-11.el8_4.i686.rpm",
"cmake-gui-debuginfo-3.18.2-11.el8_4.x86_64.rpm",
"cmake-rpm-macros-3.18.2-11.el8_4.noarch.rpm",
},
CVEs: []string{},
Fixes: []string{},
PublicationDate: "2021-06-29T00:00:00Z",
},
}
env := getPollRedHatErrataEnv()
env.ExecuteWorkflow(controller.PollRedHatErrataWorkflow)
require.Nil(t, env.GetWorkflowError())
cves := mockDb.Cves
require.Len(t, cves, 1)
require.Equal(t, "RHBA-2021:2593", cves[0].ID)
affectedProducts, _ := controller.db.GetAllAffectedProductsByCVE(cves[0].ID)
require.Len(t, affectedProducts, 1)
require.Equal(t, "cmake-3.18.2-11.el8_4", affectedProducts[0].Package)
require.Equal(t, int(apollopb.AffectedProduct_STATE_FIXED_UPSTREAM), affectedProducts[0].State)
}

View File

@ -1,112 +0,0 @@
{
"threat_severity": "Moderate",
"public_date": "2021-07-15T14:00:00Z",
"bugzilla": {
"description": "CVE-2021-3602 buildah: Host environment variables leaked in build container when using chroot isolation",
"id": "1969264",
"url": "https://bugzilla.redhat.com/show_bug.cgi?id=1969264"
},
"cvss3": {
"cvss3_base_score": "5.6",
"cvss3_scoring_vector": "CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:C/C:H/I:N/A:N",
"status": "verified"
},
"cwe": "CWE-200",
"details": [
"An information disclosure flaw was found in Buildah, when building containers using chroot isolation. Running processes in container builds (e.g. Dockerfile RUN commands) can access environment variables from parent and grandparent processes. When run in a container in a CI/CD environment, environment variables may include sensitive information that was shared with the container in order to be used only by Buildah itself (e.g. container registry credentials).",
"An information disclosure flaw was found in Buildah, when building containers using chroot isolation. Running processes in container builds (e.g. Dockerfile RUN commands) can access environment variables from parent and grandparent processes. When run in a container in a CI/CD environment, environment variables may include sensitive information that was shared with the container in order to be used only by Buildah itself (e.g. container registry credentials)."
],
"statement": "OpenShift Container Platform 4's builder container is not vulnerable to this flaw as it uses OCI isolation (i.e. using runc) and does not use chroot isolation.",
"acknowledgement": "Red Hat would like to thank Blake Burkhart for reporting this issue.",
"affected_release": [
{
"product_name": "Red Hat Enterprise Linux 8",
"release_date": "2021-11-09T00:00:00Z",
"advisory": "RHSA-2021:4154",
"cpe": "cpe:/a:redhat:enterprise_linux:8",
"package": "container-tools:rhel8-8050020210921082437.faa19cc5"
},
{
"product_name": "Red Hat Enterprise Linux 8",
"release_date": "2021-11-09T00:00:00Z",
"advisory": "RHSA-2021:4221",
"cpe": "cpe:/a:redhat:enterprise_linux:8",
"package": "container-tools:2.0-8050020210817115648.faa19cc5"
},
{
"product_name": "Red Hat Enterprise Linux 8",
"release_date": "2021-11-09T00:00:00Z",
"advisory": "RHSA-2021:4222",
"cpe": "cpe:/a:redhat:enterprise_linux:8",
"package": "container-tools:3.0-8050020210915114620.faa19cc5"
}
],
"package_state": [
{
"product_name": "Red Hat Enterprise Linux 7",
"fix_state": "Out of support scope",
"package_name": "buildah",
"cpe": "cpe:/o:redhat:enterprise_linux:7"
},
{
"product_name": "Red Hat Enterprise Linux 7",
"fix_state": "Out of support scope",
"package_name": "podman",
"cpe": "cpe:/o:redhat:enterprise_linux:7"
},
{
"product_name": "Red Hat Enterprise Linux 9",
"fix_state": "Not affected",
"package_name": "buildah",
"cpe": "cpe:/o:redhat:enterprise_linux:9"
},
{
"product_name": "Red Hat Enterprise Linux 9",
"fix_state": "Not affected",
"package_name": "podman",
"cpe": "cpe:/o:redhat:enterprise_linux:9"
},
{
"product_name": "Red Hat OpenShift Container Platform 3.11",
"fix_state": "Will not fix",
"package_name": "podman",
"cpe": "cpe:/a:redhat:openshift:3.11"
},
{
"product_name": "Red Hat OpenShift Container Platform 4",
"fix_state": "Will not fix",
"package_name": "buildah",
"cpe": "cpe:/a:redhat:openshift:4"
},
{
"product_name": "Red Hat OpenShift Container Platform 4",
"fix_state": "Not affected",
"package_name": "cri-o",
"cpe": "cpe:/a:redhat:openshift:4"
},
{
"product_name": "Red Hat OpenShift Container Platform 4",
"fix_state": "Not affected",
"package_name": "openshift4/ose-docker-builder",
"cpe": "cpe:/a:redhat:openshift:4"
},
{
"product_name": "Red Hat OpenShift Container Platform 4",
"fix_state": "Will not fix",
"package_name": "podman",
"cpe": "cpe:/a:redhat:openshift:4"
},
{
"product_name": "Red Hat Quay 3",
"fix_state": "Affected",
"package_name": "quay/quay-builder-rhel8",
"cpe": "cpe:/a:redhat:quay:3"
}
],
"upstream_fix": "buildah 1.16.8, buildah 1.19.9, buildah 1.17.2, buildah 1.21.3",
"references": [
"https://github.com/containers/buildah/security/advisories/GHSA-7638-r9r3-rmjj"
],
"name": "CVE-2021-3602",
"csaw": false
}

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