not working so far
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed

This commit is contained in:
2025-06-20 14:33:42 +02:00
parent 28e17de0f1
commit 8fe214372f
3 changed files with 191 additions and 0 deletions

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
local_imports/
ENV ENV
defs/ defs/
*/.venv/ */.venv/

12
go.mod Normal file
View File

@ -0,0 +1,12 @@
module dtrack-defectdojo-automatio-go/sbom-dd-dt
go 1.24.4
replace local_imports/defectdojo-client-go => ./local_imports/defectdojo-client-go
replace local_imports/dependencytrack-client-go => ./local_imports/dependencytrack-client-go
require (
local_imports/defectdojo-client-go v0.0.0-00010101000000-000000000000
local_imports/dependencytrack-client-go v0.0.0-00010101000000-000000000000
)

178
src/sbom-dd-dt/main.go Normal file
View File

@ -0,0 +1,178 @@
package main
import (
"bytes"
"context"
"errors"
"fmt"
"io/ioutil"
"log"
"os"
"os/exec"
"strconv"
"time"
defectdojo_api "local_imports/defectdojo-client-go"
dependencytrack_api "local_imports/dependencytrack-client-go"
)
var verbose bool
func mustEnv(key string) string {
val, ok := os.LookupEnv(key)
if !ok {
log.Fatalf("Missing required env variable: %s", key)
}
return val
}
func generateSBOM(target, name, version string) ([]byte, error) {
cmd := exec.Command("syft", "scan", target, "-o", "cyclonedx-json", "--source-name", name, "--source-version", version)
var out, stderr bytes.Buffer
cmd.Stdout = &out
cmd.Stderr = &stderr
err := cmd.Run()
if err != nil {
log.Println("SBOM generation failed:", stderr.String())
return nil, err
}
return out.Bytes(), nil
}
func main() {
// Load env
dtrackURL := mustEnv("DTRACK_API_URL")
dtrackToken := mustEnv("DTRACK_TOKEN")
defectdojoURL := mustEnv("DEFECTDOJO_URL")
defectdojoToken := mustEnv("DEFECTDOJO_TOKEN")
// Flags
projectName := os.Args[1] // Simplified args
projectVersion := os.Args[2]
projectDescription := os.Args[3]
productType, _ := strconv.Atoi(os.Args[4])
projectClassifier := os.Args[5]
sbomFile := os.Args[6] // optional
// Get SBOM
var sbom []byte
var err error
if sbomFile != "" {
sbom, err = os.ReadFile(sbomFile)
if err != nil {
log.Fatalf("Could not read SBOM file: %v", err)
}
} else {
sbom, err = generateSBOM(".", projectName, projectVersion)
if err != nil {
log.Fatalf("Failed to generate SBOM: %v", err)
}
}
// DefectDojo client
ddConfig := defectdojo_api.NewConfiguration()
ddConfig.Servers = defectdojo_api.ServerConfigurations{
{URL: defectdojoURL},
}
ddConfig.AddDefaultHeader("Authorization", "Token "+defectdojoToken)
ddClient := defectdojo_api.NewAPIClient(ddConfig)
ctx := context.Background()
// Create product
prodReq := defectdojo_api.ProductRequest{
Name: projectName + ":" + projectVersion,
Description: projectDescription,
ProdType: int32(productType),
}
prodResp, _, err := ddClient.ProductsAPI.ProductsCreate(ctx).ProductRequest(prodReq).Execute()
if err != nil {
log.Fatalf("Failed to create product: %v", err)
}
log.Println("Created product:", prodResp.Id)
// Create engagement
now := time.Now()
end := now.AddDate(10, 0, 0)
engagementReq := defectdojo_api.EngagementRequest{
Name: projectName + " DTrack Link",
TargetStart: now.Format("2006-01-02"),
TargetEnd: end.Format("2006-01-02"),
Status: "In Progress",
Product: prodResp.Id,
}
engagementResp, _, err := ddClient.EngagementsAPI.EngagementsCreate(ctx).EngagementRequest(engagementReq).Execute()
if err != nil {
log.Fatalf("Failed to create engagement: %v", err)
}
log.Println("Created engagement:", engagementResp.Id)
// DependencyTrack client
dtConfig := dependencytrack_api.NewConfiguration()
dtConfig.Servers = dependencytrack_api.ServerConfigurations{
{URL: dtrackURL + "/api"},
}
dtConfig.AddDefaultHeader("X-Api-Key", dtrackToken)
dtClient := dependencytrack_api.NewAPIClient(dtConfig)
// Create project
projectReq := dependencytrack_api.Project{
Name: &projectName,
Version: &projectVersion,
Classifier: &projectClassifier,
}
projectResp, _, err := dtClient.ProjectApi.CreateProject(ctx).Project(projectReq).Execute()
if err != nil {
log.Fatalf("Failed to create DTrack project: %v", err)
}
log.Println("Created DTrack project UUID:", *projectResp.Uuid)
// Set properties
properties := []dependencytrack_api.ProjectProperty{
{
GroupName: ptr("integrations"),
PropertyName: ptr("defectdojo.engagementId"),
PropertyValue: ptr(fmt.Sprintf("%d", *engagementResp.Id)),
PropertyType: ptr("STRING"),
},
{
GroupName: ptr("integrations"),
PropertyName: ptr("defectdojo.doNotReactivate"),
PropertyValue: ptr("true"),
PropertyType: ptr("BOOLEAN"),
},
{
GroupName: ptr("integrations"),
PropertyName: ptr("defectdojo.reimport"),
PropertyValue: ptr("true"),
PropertyType: ptr("BOOLEAN"),
},
}
for _, p := range properties {
_, err := dtClient.ProjectPropertyApi.CreateProperty1(ctx, *projectResp.Uuid).ProjectProperty(p).Execute()
if err != nil {
log.Fatalf("Failed to create property: %v", err)
}
}
// Upload SBOM
_, err = dtClient.BomApi.UploadBom(ctx).
ProjectName(projectName).
ProjectVersion(projectVersion).
AutoCreate(true).
Bom(string(sbom)).
Execute()
if err != nil {
log.Fatalf("Failed to upload SBOM: %v", err)
}
log.Println("SBOM uploaded successfully")
}
func ptr[T any](v T) *T {
return &v
}