diff --git a/cmd/fortifyExecuteScan_generated.go b/cmd/fortifyExecuteScan_generated.go index 3f09155cb..6d6bb83d8 100644 --- a/cmd/fortifyExecuteScan_generated.go +++ b/cmd/fortifyExecuteScan_generated.go @@ -6,14 +6,18 @@ import ( "fmt" "os" "path/filepath" + "reflect" + "strings" "time" "github.com/SAP/jenkins-library/pkg/config" + "github.com/SAP/jenkins-library/pkg/gcs" "github.com/SAP/jenkins-library/pkg/log" "github.com/SAP/jenkins-library/pkg/piperenv" "github.com/SAP/jenkins-library/pkg/splunk" "github.com/SAP/jenkins-library/pkg/telemetry" "github.com/SAP/jenkins-library/pkg/validation" + "github.com/bmatcuk/doublestar" "github.com/spf13/cobra" ) @@ -144,6 +148,46 @@ func (i *fortifyExecuteScanInflux) persist(path, resourceName string) { } } +type fortifyExecuteScanReports struct { +} + +func (p *fortifyExecuteScanReports) persist(stepConfig fortifyExecuteScanOptions, gcpJsonKeyFilePath string, gcsBucketId string, gcsFolderPath string, gcsSubFolder string) { + if gcsBucketId == "" { + log.Entry().Info("persisting reports to GCS is disabled, because gcsBucketId is empty") + return + } + log.Entry().Info("Uploading reports to Google Cloud Storage...") + content := []gcs.ReportOutputParam{ + {FilePattern: "**/*.PDF", ParamRef: "", StepResultType: "fortify"}, + {FilePattern: "**/*.fpr", ParamRef: "", StepResultType: "fortify"}, + {FilePattern: "**/fortify-scan.*", ParamRef: "", StepResultType: "fortify"}, + {FilePattern: "**/toolrun_fortify_*.json", ParamRef: "", StepResultType: "fortify"}, + {FilePattern: "**/piper_fortify_report.json", ParamRef: "", StepResultType: "fortify"}, + {FilePattern: "**/piper_fortify_report.html", ParamRef: "", StepResultType: "fortify"}, + } + envVars := []gcs.EnvVar{ + {Name: "GOOGLE_APPLICATION_CREDENTIALS", Value: gcpJsonKeyFilePath, Modified: false}, + } + gcsClient, err := gcs.NewClient(gcs.WithEnvVars(envVars)) + if err != nil { + log.Entry().Errorf("creation of GCS client failed: %v", err) + } + defer gcsClient.Close() + structVal := reflect.ValueOf(&stepConfig).Elem() + inputParameters := map[string]string{} + for i := 0; i < structVal.NumField(); i++ { + field := structVal.Type().Field(i) + if field.Type.String() == "string" { + paramName := strings.Split(field.Tag.Get("json"), ",") + paramValue, _ := structVal.Field(i).Interface().(string) + inputParameters[paramName[0]] = paramValue + } + } + if err := gcs.PersistReportsToGCS(gcsClient, content, inputParameters, gcsFolderPath, gcsBucketId, gcsSubFolder, doublestar.Glob, os.Stat); err != nil { + log.Entry().Errorf("failed to persist reports: %v", err) + } +} + // FortifyExecuteScanCommand This step executes a Fortify scan on the specified project to perform static code analysis and check the source code for security flaws. func FortifyExecuteScanCommand() *cobra.Command { const STEP_NAME = "fortifyExecuteScan" @@ -152,6 +196,7 @@ func FortifyExecuteScanCommand() *cobra.Command { var stepConfig fortifyExecuteScanOptions var startTime time.Time var influx fortifyExecuteScanInflux + var reports fortifyExecuteScanReports var logCollector *log.CollectorHook var splunkClient *splunk.Splunk telemetryClient := &telemetry.Telemetry{} @@ -217,6 +262,7 @@ Besides triggering a scan the step verifies the results after they have been upl stepTelemetryData.ErrorCode = "1" handler := func() { influx.persist(GeneralConfig.EnvRootPath, "influx") + reports.persist(stepConfig, GeneralConfig.GCPJsonKeyFilePath, GeneralConfig.GCSBucketId, GeneralConfig.GCSFolderPath, GeneralConfig.GCSSubFolder) config.RemoveVaultSecretFiles() stepTelemetryData.Duration = fmt.Sprintf("%v", time.Since(startTime).Milliseconds()) stepTelemetryData.ErrorCategory = log.GetErrorCategory().String() @@ -923,6 +969,18 @@ func fortifyExecuteScanMetadata() config.StepData { {"name": "fortify_data", "fields": []map[string]string{{"name": "projectName"}, {"name": "projectVersion"}, {"name": "projectVersionId"}, {"name": "violations"}, {"name": "corporateTotal"}, {"name": "corporateAudited"}, {"name": "auditAllTotal"}, {"name": "auditAllAudited"}, {"name": "spotChecksTotal"}, {"name": "spotChecksAudited"}, {"name": "spotChecksGap"}, {"name": "suspicious"}, {"name": "exploitable"}, {"name": "suppressed"}}}, }, }, + { + Name: "reports", + Type: "reports", + Parameters: []map[string]interface{}{ + {"filePattern": "**/*.PDF", "type": "fortify"}, + {"filePattern": "**/*.fpr", "type": "fortify"}, + {"filePattern": "**/fortify-scan.*", "type": "fortify"}, + {"filePattern": "**/toolrun_fortify_*.json", "type": "fortify"}, + {"filePattern": "**/piper_fortify_report.json", "type": "fortify"}, + {"filePattern": "**/piper_fortify_report.html", "type": "fortify"}, + }, + }, }, }, }, diff --git a/resources/metadata/fortifyExecuteScan.yaml b/resources/metadata/fortifyExecuteScan.yaml index 027bc5cfe..783ab0c90 100644 --- a/resources/metadata/fortifyExecuteScan.yaml +++ b/resources/metadata/fortifyExecuteScan.yaml @@ -666,3 +666,18 @@ spec: type: int - name: suppressed type: int + - name: reports + type: reports + params: + - filePattern: "**/*.PDF" + type: fortify + - filePattern: "**/*.fpr" + type: fortify + - filePattern: "**/fortify-scan.*" + type: fortify + - filePattern: "**/toolrun_fortify_*.json" + type: fortify + - filePattern: "**/piper_fortify_report.json" + type: fortify + - filePattern: "**/piper_fortify_report.html" + type: fortify