This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,3 +1,4 @@
|
||||
local_imports/
|
||||
ENV
|
||||
defs/
|
||||
*/.venv/
|
||||
|
12
go.mod
Normal file
12
go.mod
Normal 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
178
src/sbom-dd-dt/main.go
Normal 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
|
||||
}
|
Reference in New Issue
Block a user