Skip to content

Commit

Permalink
Merge branch 'main' into feature/ocu-118-semgrep-and-bandit-producers…
Browse files Browse the repository at this point in the history
…-dont-propagate-cwe
  • Loading branch information
flowirtz authored Jun 6, 2024
2 parents d822a9e + db05659 commit 131acab
Show file tree
Hide file tree
Showing 12 changed files with 81 additions and 53 deletions.
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,8 @@ clean: clean-protos clean-migrations-compose
.PHONY: lint install-lint-tools tests go-tests fmt fmt-proto fmt-go install-go-fmt-tools migration-tests

lint:
@reviewdog -fail-on-error $$([ "${CI}" = "true" ] && echo "-reporter=github-pr-review") -diff="git diff origin/main" -filter-mode=added -tee
# we need to redirect stderr to stdout because Github actions don't capture the stderr lolz
@reviewdog -fail-on-error -diff="git diff origin/main" -filter-mode=added 2>&1

install-lint-tools:
@go install honnef.co/go/tools/cmd/staticcheck@latest
Expand Down
4 changes: 2 additions & 2 deletions cmd/draconctl/main.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package main

import (
"log/slog"
"os"

"github.com/spf13/cobra"
Expand All @@ -20,11 +21,10 @@ func main() {
ID: "top-level",
Title: "Top-level Commands:",
})

pipelines.RegisterPipelinesSubcommands(rootCmd)
migrations.RegisterMigrationsSubcommands(rootCmd)
components.RegisterComponentsSubcommands(rootCmd)

slog.SetDefault(slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{})))
err := rootCmd.Execute()
if err != nil {
os.Exit(1)
Expand Down
10 changes: 10 additions & 0 deletions components/component.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package components

const (
// EnvDraconStartTime Start Time of Dracon Scan in RFC3339.
EnvDraconStartTime = "DRACON_SCAN_TIME"
// EnvDraconScanID the ID of the dracon scan.
EnvDraconScanID = "DRACON_SCAN_ID"
// EnvDraconScanTags the tags of the dracon scan.
EnvDraconScanTags = "DRACON_SCAN_TAGS"
)
29 changes: 16 additions & 13 deletions components/consumers/consumer.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,47 +5,50 @@ package consumers
import (
"flag"
"fmt"
"log/slog"
"os"

v1 "github.com/ocurity/dracon/api/proto/v1"

draconapiv1 "github.com/ocurity/dracon/api/proto/v1"
"github.com/ocurity/dracon/components"
"github.com/ocurity/dracon/pkg/putil"
)

const (
// EnvDraconStartTime Start Time of Dracon Scan in RFC3339.
EnvDraconStartTime = "DRACON_SCAN_TIME"
// EnvDraconScanID the ID of the dracon scan.
EnvDraconScanID = "DRACON_SCAN_ID"
// EnvDraconScanTags the tags of the dracon scan.
EnvDraconScanTags = "DRACON_SCAN_TAGS"
)

var (
inResults string
// Raw represents if the non-enriched results should be used.
Raw bool
// debug flag initializes the logger with a debug level
debug bool
)

func init() {
flag.StringVar(&inResults, "in", "", "the directory where dracon producer/enricher outputs are")
flag.BoolVar(&Raw, "raw", false, "if the non-enriched results should be used")
flag.BoolVar(&debug, "debug", false, "turn on debug logging")
}

// ParseFlags will parse the input flags for the consumer and perform simple validation.
func ParseFlags() error {
flag.Parse()

logLevel := slog.LevelInfo
if debug {
logLevel = slog.LevelDebug
}

slog.SetDefault(slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{Level: logLevel})).With("scanID", os.Getenv(components.EnvDraconScanID)))
if len(inResults) < 1 {
return fmt.Errorf("in is undefined")
}
return nil
}

// LoadToolResponse loads raw results from producers.
func LoadToolResponse() ([]*v1.LaunchToolResponse, error) {
func LoadToolResponse() ([]*draconapiv1.LaunchToolResponse, error) {
return putil.LoadToolResponse(inResults)
}

// LoadEnrichedToolResponse loads enriched results from the enricher.
func LoadEnrichedToolResponse() ([]*v1.EnrichedLaunchToolResponse, error) {
func LoadEnrichedToolResponse() ([]*draconapiv1.EnrichedLaunchToolResponse, error) {
return putil.LoadEnrichedToolResponse(inResults)
}
12 changes: 6 additions & 6 deletions components/consumers/consumer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ import (
"testing"
"time"

v1 "github.com/ocurity/dracon/api/proto/v1"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

draconapiv1 "github.com/ocurity/dracon/api/proto/v1"
"github.com/ocurity/dracon/components"
"github.com/ocurity/dracon/pkg/putil"
)

Expand All @@ -23,7 +23,7 @@ func TestLoadToolResponse(t *testing.T) {

defer require.NoError(t, os.Remove(tmpFile.Name()))

issues := []*v1.Issue{
issues := []*draconapiv1.Issue{
{
Target: "/dracon/source/foobar",
Title: "/dracon/source/barfoo",
Expand All @@ -39,9 +39,9 @@ func TestLoadToolResponse(t *testing.T) {
scanTags, err := json.Marshal(tags)
assert.NoError(t, err)

require.NoError(t, os.Setenv(EnvDraconStartTime, timestamp))
require.NoError(t, os.Setenv(EnvDraconScanID, scanID))
require.NoError(t, os.Setenv(EnvDraconScanTags, string(scanTags)))
require.NoError(t, os.Setenv(components.EnvDraconStartTime, timestamp))
require.NoError(t, os.Setenv(components.EnvDraconScanID, scanID))
require.NoError(t, os.Setenv(components.EnvDraconScanTags, string(scanTags)))

resultTempDir := tmpFile.Name()
resultFile := "test-tool"
Expand Down
37 changes: 20 additions & 17 deletions components/producers/producer.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,14 @@ import (
"flag"
"fmt"
"io"
"log"
"log/slog"
"os"
"path/filepath"
"strings"
"time"

v1 "github.com/ocurity/dracon/api/proto/v1"
draconapiv1 "github.com/ocurity/dracon/api/proto/v1"
"github.com/ocurity/dracon/components"

"github.com/ocurity/dracon/pkg/putil"
)
Expand All @@ -28,26 +29,28 @@ var (
OutFile string
// Append flag will append to the outfile instead of overwriting, useful when there's multiple inresults.
Append bool
// debug flag initializes the logger with a debug level
debug bool
)

const (
sourceDir = "/workspace/output"

// EnvDraconStartTime Start Time of Dracon Scan in RFC3339.
EnvDraconStartTime = "DRACON_SCAN_TIME"
// EnvDraconScanID the ID of the dracon scan.
EnvDraconScanID = "DRACON_SCAN_ID"
// EnvDraconScanTags the tags of the dracon scan.
EnvDraconScanTags = "DRACON_SCAN_TAGS"
)

// ParseFlags will parse the input flags for the producer and perform simple validation.
func ParseFlags() error {
flag.StringVar(&InResults, "in", "", "")
flag.StringVar(&OutFile, "out", "", "")
flag.BoolVar(&debug, "debug", false, "turn on debug logging")
flag.BoolVar(&Append, "append", false, "Append to output file instead of overwriting it")

flag.Parse()
logLevel := slog.LevelInfo
if debug {
logLevel = slog.LevelDebug
}
slog.SetDefault(slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{Level: logLevel})).With("scanID", os.Getenv(components.EnvDraconScanID)))

if InResults == "" {
return fmt.Errorf("in is undefined")
}
Expand Down Expand Up @@ -113,28 +116,28 @@ func ParseMultiJSONMessages(in []byte) ([]interface{}, error) {
// WriteDraconOut provides a generic method to write the resulting protobuf to the output file.
func WriteDraconOut(
toolName string,
issues []*v1.Issue,
issues []*draconapiv1.Issue,
) error {
source := getSource()
cleanIssues := []*v1.Issue{}
cleanIssues := []*draconapiv1.Issue{}
for _, iss := range issues {
iss.Description = strings.ReplaceAll(iss.Description, sourceDir, ".")
iss.Title = strings.ReplaceAll(iss.Title, sourceDir, ".")
iss.Target = strings.ReplaceAll(iss.Target, sourceDir, ".")
iss.Source = source
cleanIssues = append(cleanIssues, iss)
log.Printf("found issue: %+v\n", iss)
slog.Info(fmt.Sprintf("found issue: %+v\n", iss))
}
scanStartTime := strings.TrimSpace(os.Getenv(EnvDraconStartTime))
scanStartTime := strings.TrimSpace(os.Getenv(components.EnvDraconStartTime))
if scanStartTime == "" {
scanStartTime = time.Now().UTC().Format(time.RFC3339)
}
scanUUUID := strings.TrimSpace(os.Getenv(EnvDraconScanID))
scanTagsStr := strings.TrimSpace(os.Getenv(EnvDraconScanTags))
scanUUUID := strings.TrimSpace(os.Getenv(components.EnvDraconScanID))
scanTagsStr := strings.TrimSpace(os.Getenv(components.EnvDraconScanTags))
scanTags := map[string]string{}
err := json.Unmarshal([]byte(scanTagsStr), &scanTags)
if err != nil {
log.Printf("scan with uuid %s does not have any tags, err:%s", scanUUUID, err)
slog.Error(fmt.Sprintf("scan does not have any tags, err:%s", err))
}

stat, err := os.Stat(OutFile)
Expand All @@ -153,7 +156,7 @@ func getSource() string {

dat, err := os.ReadFile(sourceMetaPath)
if err != nil {
log.Println(err)
slog.Error(err.Error())
}
return strings.TrimSpace(string(dat))
}
9 changes: 5 additions & 4 deletions components/producers/producer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"time"

v1 "github.com/ocurity/dracon/api/proto/v1"
"github.com/ocurity/dracon/components"

"github.com/mitchellh/mapstructure"
"github.com/stretchr/testify/assert"
Expand All @@ -25,8 +26,8 @@ func TestWriteDraconOut(t *testing.T) {

baseTime := time.Now().UTC()
timestamp := baseTime.Format(time.RFC3339)
require.NoError(t, os.Setenv(EnvDraconStartTime, timestamp))
require.NoError(t, os.Setenv(EnvDraconScanID, "ab3d3290-cd9f-482c-97dc-ec48bdfcc4de"))
require.NoError(t, os.Setenv(components.EnvDraconStartTime, timestamp))
require.NoError(t, os.Setenv(components.EnvDraconScanID, "ab3d3290-cd9f-482c-97dc-ec48bdfcc4de"))

OutFile = tmpFile.Name()
Append = false
Expand Down Expand Up @@ -66,8 +67,8 @@ func TestWriteDraconOutAppend(t *testing.T) {

baseTime := time.Now().UTC()
timestamp := baseTime.Format(time.RFC3339)
require.NoError(t, os.Setenv(EnvDraconStartTime, timestamp))
require.NoError(t, os.Setenv(EnvDraconScanID, "ab3d3290-cd9f-482c-97dc-ec48bdfcc4de"))
require.NoError(t, os.Setenv(components.EnvDraconStartTime, timestamp))
require.NoError(t, os.Setenv(components.EnvDraconScanID, "ab3d3290-cd9f-482c-97dc-ec48bdfcc4de"))

OutFile = tmpFile.Name()
Append = true
Expand Down
2 changes: 1 addition & 1 deletion deploy/dracon/chart/templates/kb-ingress.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{{ if .Values.kibana.enabled }}
{{ if .Values.kibana.ingress.enabled }}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
Expand Down
2 changes: 1 addition & 1 deletion deploy/dracon/chart/templates/migrations-job.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ metadata:
# job is considered part of the release.
"helm.sh/hook": post-install,post-upgrade
"helm.sh/hook-weight": "-5"
"helm.sh/hook-delete-policy": hook-succeeded
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded, hook-failed
spec:
template:
metadata:
Expand Down
3 changes: 0 additions & 3 deletions deploy/dracon/chart/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,6 @@ postgresql:
postgresPassword: ""
fullnameOverride: ""

tekton:
enabled: true

# this section controls aspects of managing a database used to store enrichments
# the database should use the Postgres dialect.
enrichmentDB:
Expand Down
1 change: 1 addition & 0 deletions deploy/dracon/values/dev.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ kibana:
enabled: true
version: 8.3.2
ingress:
enabled: true
className: nginx
host: kibana.dracon.localhost
tlsEnabled: false
Expand Down
22 changes: 17 additions & 5 deletions pkg/k8s/fake/clientset.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (

tektonv1beta1api "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1"
tektonv1beta1fakeclient "github.com/tektoncd/pipeline/pkg/client/clientset/versioned/typed/pipeline/v1beta1/fake"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/api/meta/testrestmapper"
"k8s.io/apimachinery/pkg/runtime"
Expand Down Expand Up @@ -39,9 +40,9 @@ func NewSchemeAndCodecs() (*runtime.Scheme, *serializer.CodecFactory, error) {

var _ k8s.ClientInterface = (*DraconClientSet)(nil)

// ApplyHookType is the signature of the function that will be called to mock
// an Apply invocation
type ApplyHookType func(clientset ClientsetSubset, obj runtime.Object, namespace string, forceConflicts bool) error
// ApplyHookType is the signature of the function that will be called to
// examine the parameters that the apply function was called with.
type ApplyHookType func(obj runtime.Object, namespace string, forceConflicts bool) error

// ClientsetSubset is just the fake clientset struct
type ClientsetSubset struct {
Expand All @@ -52,6 +53,7 @@ type ClientsetSubset struct {
// DraconClientSet is a mock implementation of the `k8s.Clientset`
type DraconClientSet struct {
ClientsetSubset
objectTracker testing.ObjectTracker
discovery *fakediscovery.FakeDiscovery
ApplyHook ApplyHookType
MetaRESTMapper meta.RESTMapper
Expand All @@ -62,7 +64,7 @@ type DraconClientSet struct {
// a correct response for all known types offered by the `k8s.ClientInterface`.
func NewFakeTypedClient(objects ...runtime.Object) (DraconClientSet, error) {
return NewFakeTypedClientWithApplyHook(
func(_ ClientsetSubset, _ runtime.Object, _ string, _ bool) error { return nil },
func(_ runtime.Object, _ string, _ bool) error { return nil },
objects...,
)
}
Expand Down Expand Up @@ -96,6 +98,7 @@ func NewFakeTypedClientWithApplyHook(applyHook ApplyHookType, objects ...runtime
})

return DraconClientSet{
objectTracker: objectTracker,
discovery: &fakediscovery.FakeDiscovery{
Fake: &fakeCoreK8sClient.Fake,
FakedServerVersion: &version.Info{
Expand All @@ -118,7 +121,16 @@ func NewFakeTypedClientWithApplyHook(applyHook ApplyHookType, objects ...runtime

// Apply mocks the `kubectl apply`
func (f DraconClientSet) Apply(_ context.Context, obj runtime.Object, namespace string, forceConflicts bool) error {
return f.ApplyHook(f.ClientsetSubset, obj, namespace, forceConflicts)
if err := f.ApplyHook(obj, namespace, forceConflicts); err != nil {
return err
}
gvk := obj.GetObjectKind().GroupVersionKind()
gvr, _ := meta.UnsafeGuessKindToResource(gvk)

if err := f.objectTracker.Create(gvr, obj, namespace); k8serrors.IsAlreadyExists(err) {
return f.objectTracker.Update(gvr, obj, namespace)
}
return nil
}

// RESTMapper returns an instance implementing the `meta.RESTMapper` interface
Expand Down

0 comments on commit 131acab

Please sign in to comment.