diff --git a/components/consumers/aws-s3/BUILD b/components/consumers/aws-s3/BUILD new file mode 100644 index 000000000..fcc5e2bd9 --- /dev/null +++ b/components/consumers/aws-s3/BUILD @@ -0,0 +1,32 @@ +subinclude( + "//build/defs:buildkit", + "//build/defs:dracon", +) + +go_binary( + name = "aws-s3", + srcs = [ + "main.go", + ], + static = True, + deps = [ + "//api/proto/v1", + "//components/consumers", + "//pkg/enumtransformers", + "//third_party/go/github.com/aws/aws-sdk-go", + ], +) + +buildkit_distroless_image( + name = "image", + srcs = [":aws-s3"], +) + +dracon_component( + name = "aws-s3", + images = [ + ":image", + ], + task = "task.yaml", + visibility = ["//examples/pipelines/..."], +) diff --git a/components/consumers/aws-s3/kustomization.yaml b/components/consumers/aws-s3/kustomization.yaml new file mode 100644 index 000000000..395405fac --- /dev/null +++ b/components/consumers/aws-s3/kustomization.yaml @@ -0,0 +1,86 @@ +# DO NOT EDIT. Code generated by: +# github.com/ocurity/dracon//build/tools/kustomize-component-generator. + +apiVersion: kustomize.config.k8s.io/v1alpha1 +kind: Component +resources: + - task.yaml +patches: + # Add the Task to the Tekton Pipeline. + - patch: | + apiVersion: tekton.dev/v1beta1 + kind: Pipeline + metadata: + name: unused + spec: + workspaces: + - name: source-code-ws + tasks: + - name: consumer-aws-s3 + taskRef: + name: consumer-aws-s3 + workspaces: + - name: source-code-ws + workspace: source-code-ws + params: + - name: consumer-aws-s3-access-key-id + value: $(params.consumer-aws-s3-access-key-id) + - name: consumer-aws-s3-secret-access-key + value: $(params.consumer-aws-s3-secret-access-key) + - name: consumer-aws-s3-bucket-name + value: $(params.consumer-aws-s3-bucket-name) + - name: consumer-aws-s3-bucket-region + value: $(params.consumer-aws-s3-bucket-region) + params: + - name: consumer-aws-s3-access-key-id + type: string + - name: consumer-aws-s3-secret-access-key + type: string + - name: consumer-aws-s3-bucket-name + type: string + - name: consumer-aws-s3-bucket-region + type: string + target: + kind: Pipeline + # Add anchors to Task. + - patch: | + apiVersion: tekton.dev/v1beta1 + kind: Task + metadata: + name: consumer-aws-s3 + labels: + v1.dracon.ocurity.com/component: consumer + spec: + params: + - name: anchors + type: array + description: A list of tasks that this task depends on using their anchors. + default: [] + results: + - name: anchor + description: An anchor to allow other tasks to depend on this task. + steps: + - name: anchor + image: docker.io/busybox:1.35.0 + script: echo "$(context.task.name)" > "$(results.anchor.path)" + target: + kind: Task + name: consumer-aws-s3 + # If we have an enricher-aggregator task in the pipeline (added by the + # enricher-aggregator component), make the consumer depend on the completion of + # it. + - patch: | + apiVersion: tekton.dev/v1beta1 + kind: Pipeline + metadata: + name: unused + spec: + tasks: + - name: consumer-aws-s3 + params: + - name: anchors + value: + - $(tasks.enricher-aggregator.results.anchor) + target: + kind: Pipeline + annotationSelector: v1.dracon.ocurity.com/has-enricher-aggregator=true diff --git a/components/consumers/aws-s3/main.go b/components/consumers/aws-s3/main.go new file mode 100644 index 000000000..3a29c5a8d --- /dev/null +++ b/components/consumers/aws-s3/main.go @@ -0,0 +1,78 @@ +// Package main of the aws-s3 consumer implements a simple consumer for +// uploading dracon results to the S3 bucket passed as an argument +// the consumer expects the environment variables +// AWS_ACCESS_KEY_ID +// AWS_SECRET_ACCESS_KEY +// to be set +package main + +import ( + "bytes" + "encoding/json" + "flag" + "fmt" + "log" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/session" + "github.com/aws/aws-sdk-go/service/s3/s3manager" + + "github.com/ocurity/dracon/components/consumers" +) + +var ( + bucket string + region string +) + +func main() { + flag.StringVar(&bucket, "bucket", "", "s3 bucket name") + flag.StringVar(®ion, "region", "", "s3 bucket region") + if err := consumers.ParseFlags(); err != nil { + log.Fatal(err) + } + if consumers.Raw { + responses, err := consumers.LoadToolResponse() + if err != nil { + log.Fatal("could not load raw results, file malformed: ", err) + } + s3Data, err := json.Marshal(responses) + if err != nil { + log.Fatal("could not marshal results, err:", err) + } + filename := fmt.Sprintf("ocurity scan %s-%s", responses[0].GetScanInfo().GetScanUuid(), responses[0].GetToolName()) + sendToS3(filename, bucket, region, s3Data) + } else { + responses, err := consumers.LoadEnrichedToolResponse() + if err != nil { + log.Fatal("could not load enriched results, file malformed: ", err) + } + filename := fmt.Sprintf("ocurity scan %s-%s", responses[0].OriginalResults.GetScanInfo().GetScanUuid(), responses[0].OriginalResults.GetToolName()) + s3Data, err := json.Marshal(responses) + if err != nil { + log.Fatal("could not marshal results, err:", err) + } + sendToS3(filename, bucket, region, s3Data) + } +} + +func sendToS3(filename, bucket, region string, data []byte) { + sess, err := session.NewSession(&aws.Config{ + Region: aws.String(region), + }, + ) + if err != nil { + log.Fatalf("Unable to acquire AWS session in region %s, check your credentials", region) + } + uploader := s3manager.NewUploader(sess) + _, err = uploader.Upload(&s3manager.UploadInput{ + Bucket: aws.String(bucket), + Key: aws.String(filename), + Body: bytes.NewReader(data), + }) + if err != nil { + log.Fatalf("Unable to upload %q to %q, %v", filename, bucket, err) + } + + fmt.Printf("Successfully uploaded %q to %q\n", filename, bucket) +} diff --git a/components/consumers/aws-s3/task.yaml b/components/consumers/aws-s3/task.yaml new file mode 100644 index 000000000..b74e34368 --- /dev/null +++ b/components/consumers/aws-s3/task.yaml @@ -0,0 +1,45 @@ +--- +apiVersion: tekton.dev/v1beta1 +kind: Task +metadata: + name: consumer-aws-s3 + labels: + v1.dracon.ocurity.com/component: consumer +spec: + volumes: + - name: scratch + emptyDir: {} + params: + - name: consumer-aws-s3-access-key-id + type: string + - name: consumer-aws-s3-secret-access-key + type: string + - name: consumer-aws-s3-bucket-name + type: string + - name: consumer-aws-s3-bucket-region + type: string + workspaces: + - name: source-code-ws + description: The workspace containing the source-code to scan. + steps: + - name: run-consumer + imagePullPolicy: IfNotPresent + image: ghcr.io/ocurity/dracon/components/consumers/aws-s3/image:latest + env: + - name: AWS_ACCESS_KEY_ID + value: "$(params.consumer-aws-s3-access-key-id)" + - name: AWS_SECRET_ACCESS_KEY + value: "$(params.consumer-aws-s3-secret-access-key)" + command: ["/app/components/consumers/aws-s3/aws-s3"] + args: + [ + "-in", + "$(workspaces.source-code-ws.path)/.dracon/enrichers/", + "-bucket", + "$(params.consumer-aws-s3-bucket-name)", + "-region", + "$(params.consumer-aws-s3-bucket-region)", + ] + volumeMounts: + - mountPath: /scratch + name: scratch diff --git a/go.mod b/go.mod index c69546b9f..147dc8401 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,7 @@ require ( github.com/DependencyTrack/client-go v0.8.0 github.com/andygrunwald/go-jira v1.15.1 github.com/avast/retry-go/v4 v4.3.3 + github.com/aws/aws-sdk-go v1.17.7 github.com/elastic/go-elasticsearch/v8 v8.3.0 github.com/golang-migrate/migrate/v4 v4.15.1 github.com/golang/protobuf v1.5.2 @@ -44,6 +45,7 @@ require ( github.com/google/go-cmp v0.5.9 // indirect github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect github.com/googleapis/gax-go/v2 v2.7.1 // indirect + github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/klauspost/asmfmt v1.3.2 // indirect github.com/klauspost/compress v1.15.9 // indirect github.com/klauspost/cpuid/v2 v2.0.9 // indirect diff --git a/go.sum b/go.sum index c5e65ccd4..f97560e1e 100644 --- a/go.sum +++ b/go.sum @@ -138,6 +138,7 @@ github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:l github.com/avast/retry-go/v4 v4.3.3 h1:G56Bp6mU0b5HE1SkaoVjscZjlQb0oy4mezwY/cGH19w= github.com/avast/retry-go/v4 v4.3.3/go.mod h1:rg6XFaiuFYII0Xu3RDbZQkxCofFwruZKW8oEF1jpWiU= github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= +github.com/aws/aws-sdk-go v1.17.7 h1:/4+rDPe0W95KBmNGYCG+NUvdL8ssPYBMxL+aSCg6nIA= github.com/aws/aws-sdk-go v1.17.7/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go-v2 v1.8.0/go.mod h1:xEFuWz+3TYdlPRuo+CqATbeDWIWyaT5uAPwPaWtgse0= github.com/aws/aws-sdk-go-v2 v1.9.2/go.mod h1:cK/D0BBs0b/oWPIcX/Z/obahJK1TT7IPVjy53i/mX/4= @@ -659,7 +660,9 @@ github.com/jinzhu/now v1.1.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/ github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= github.com/jmoiron/sqlx v1.3.1/go.mod h1:2BljVx/86SuTyjE+aPYlHCTNvZrnJXghYGpNiXLBMCQ= diff --git a/third_party/go/github.com/aws/aws-sdk-go/BUILD b/third_party/go/github.com/aws/aws-sdk-go/BUILD new file mode 100644 index 000000000..6f17eab27 --- /dev/null +++ b/third_party/go/github.com/aws/aws-sdk-go/BUILD @@ -0,0 +1,62 @@ +go_module( + name = "aws-sdk-go", + install = [ + ".", + "aws", + "aws/arn", + "aws/auth/bearer", + "aws/awserr", + "aws/awsutil", + "aws/client", + "aws/client/metadata", + "aws/corehandlers", + "aws/credentials", + "aws/credentials/ec2rolecreds", + "aws/credentials/endpointcreds", + "aws/credentials/processcreds", + "aws/credentials/ssocreds", + "aws/credentials/stscreds", + "aws/csm", + "aws/defaults", + "aws/ec2metadata", + "aws/endpoints", + "aws/request", + "aws/session", + "aws/signer/v4", + "internal/ini", + "internal/s3shared", + "internal/s3shared/arn", + "internal/s3shared/s3err", + "internal/sdkio", + "internal/sdkmath", + "internal/sdkrand", + "internal/sdkuri", + "internal/shareddefaults", + "internal/strings", + "internal/sync/singleflight", + "private/checksum", + "private/protocol", + "private/protocol/eventstream", + "private/protocol/eventstream/eventstreamapi", + "private/protocol/json/jsonutil", + "private/protocol/jsonrpc", + "private/protocol/query", + "private/protocol/query/queryutil", + "private/protocol/rest", + "private/protocol/restjson", + "private/protocol/restxml", + "private/protocol/xml/xmlutil", + "service/s3", + "service/s3/s3iface", + "service/s3/s3manager", + "service/sso", + "service/sso/ssoiface", + "service/ssooidc", + "service/sts", + "service/sts/stsiface", + ], + module = "github.com/aws/aws-sdk-go", + version = "v1.45.24", + visibility = ["PUBLIC"], + deps = ["//third_party/go/github.com/jmespath/go-jmespath"], +) diff --git a/third_party/go/github.com/jmespath/go-jmespath/BUILD b/third_party/go/github.com/jmespath/go-jmespath/BUILD new file mode 100644 index 000000000..2371c63e6 --- /dev/null +++ b/third_party/go/github.com/jmespath/go-jmespath/BUILD @@ -0,0 +1,6 @@ +go_module( + name = "go-jmespath", + module = "github.com/jmespath/go-jmespath", + version = "v0.4.0", + visibility = ["PUBLIC"], +)