github.com/jaylevin/jenkins-library@v1.230.4/cmd/checkmarxExecuteScan_generated.go (about) 1 // Code generated by piper's step-generator. DO NOT EDIT. 2 3 package cmd 4 5 import ( 6 "fmt" 7 "os" 8 "path/filepath" 9 "reflect" 10 "strings" 11 "time" 12 13 "github.com/SAP/jenkins-library/pkg/config" 14 "github.com/SAP/jenkins-library/pkg/gcs" 15 "github.com/SAP/jenkins-library/pkg/log" 16 "github.com/SAP/jenkins-library/pkg/piperenv" 17 "github.com/SAP/jenkins-library/pkg/splunk" 18 "github.com/SAP/jenkins-library/pkg/telemetry" 19 "github.com/SAP/jenkins-library/pkg/validation" 20 "github.com/bmatcuk/doublestar" 21 "github.com/spf13/cobra" 22 ) 23 24 type checkmarxExecuteScanOptions struct { 25 Assignees []string `json:"assignees,omitempty"` 26 AvoidDuplicateProjectScans bool `json:"avoidDuplicateProjectScans,omitempty"` 27 FilterPattern string `json:"filterPattern,omitempty"` 28 FullScanCycle string `json:"fullScanCycle,omitempty"` 29 FullScansScheduled bool `json:"fullScansScheduled,omitempty"` 30 GeneratePdfReport bool `json:"generatePdfReport,omitempty"` 31 GithubAPIURL string `json:"githubApiUrl,omitempty"` 32 GithubToken string `json:"githubToken,omitempty"` 33 Incremental bool `json:"incremental,omitempty"` 34 MaxRetries int `json:"maxRetries,omitempty"` 35 Owner string `json:"owner,omitempty"` 36 Password string `json:"password,omitempty"` 37 Preset string `json:"preset,omitempty"` 38 ProjectName string `json:"projectName,omitempty"` 39 PullRequestName string `json:"pullRequestName,omitempty"` 40 Repository string `json:"repository,omitempty"` 41 ServerURL string `json:"serverUrl,omitempty"` 42 SourceEncoding string `json:"sourceEncoding,omitempty"` 43 TeamID string `json:"teamId,omitempty"` 44 TeamName string `json:"teamName,omitempty"` 45 Username string `json:"username,omitempty"` 46 VerifyOnly bool `json:"verifyOnly,omitempty"` 47 VulnerabilityThresholdEnabled bool `json:"vulnerabilityThresholdEnabled,omitempty"` 48 VulnerabilityThresholdHigh int `json:"vulnerabilityThresholdHigh,omitempty"` 49 VulnerabilityThresholdLow int `json:"vulnerabilityThresholdLow,omitempty"` 50 VulnerabilityThresholdMedium int `json:"vulnerabilityThresholdMedium,omitempty"` 51 VulnerabilityThresholdResult string `json:"vulnerabilityThresholdResult,omitempty" validate:"possible-values=FAILURE"` 52 VulnerabilityThresholdUnit string `json:"vulnerabilityThresholdUnit,omitempty"` 53 IsOptimizedAndScheduled bool `json:"isOptimizedAndScheduled,omitempty"` 54 CreateResultIssue bool `json:"createResultIssue,omitempty"` 55 ConvertToSarif bool `json:"convertToSarif,omitempty"` 56 } 57 58 type checkmarxExecuteScanInflux struct { 59 step_data struct { 60 fields struct { 61 checkmarx bool 62 } 63 tags struct { 64 } 65 } 66 checkmarx_data struct { 67 fields struct { 68 high_issues int 69 high_not_false_postive int 70 high_not_exploitable int 71 high_confirmed int 72 high_urgent int 73 high_proposed_not_exploitable int 74 high_to_verify int 75 medium_issues int 76 medium_not_false_postive int 77 medium_not_exploitable int 78 medium_confirmed int 79 medium_urgent int 80 medium_proposed_not_exploitable int 81 medium_to_verify int 82 low_issues int 83 low_not_false_postive int 84 low_not_exploitable int 85 low_confirmed int 86 low_urgent int 87 low_proposed_not_exploitable int 88 low_to_verify int 89 information_issues int 90 information_not_false_postive int 91 information_not_exploitable int 92 information_confirmed int 93 information_urgent int 94 information_proposed_not_exploitable int 95 information_to_verify int 96 lines_of_code_scanned int 97 files_scanned int 98 initiator_name string 99 owner string 100 scan_id string 101 project_id string 102 projectName string 103 team string 104 team_full_path_on_report_date string 105 scan_start string 106 scan_time string 107 checkmarx_version string 108 scan_type string 109 preset string 110 deep_link string 111 report_creation_time string 112 } 113 tags struct { 114 } 115 } 116 } 117 118 func (i *checkmarxExecuteScanInflux) persist(path, resourceName string) { 119 measurementContent := []struct { 120 measurement string 121 valType string 122 name string 123 value interface{} 124 }{ 125 {valType: config.InfluxField, measurement: "step_data", name: "checkmarx", value: i.step_data.fields.checkmarx}, 126 {valType: config.InfluxField, measurement: "checkmarx_data", name: "high_issues", value: i.checkmarx_data.fields.high_issues}, 127 {valType: config.InfluxField, measurement: "checkmarx_data", name: "high_not_false_postive", value: i.checkmarx_data.fields.high_not_false_postive}, 128 {valType: config.InfluxField, measurement: "checkmarx_data", name: "high_not_exploitable", value: i.checkmarx_data.fields.high_not_exploitable}, 129 {valType: config.InfluxField, measurement: "checkmarx_data", name: "high_confirmed", value: i.checkmarx_data.fields.high_confirmed}, 130 {valType: config.InfluxField, measurement: "checkmarx_data", name: "high_urgent", value: i.checkmarx_data.fields.high_urgent}, 131 {valType: config.InfluxField, measurement: "checkmarx_data", name: "high_proposed_not_exploitable", value: i.checkmarx_data.fields.high_proposed_not_exploitable}, 132 {valType: config.InfluxField, measurement: "checkmarx_data", name: "high_to_verify", value: i.checkmarx_data.fields.high_to_verify}, 133 {valType: config.InfluxField, measurement: "checkmarx_data", name: "medium_issues", value: i.checkmarx_data.fields.medium_issues}, 134 {valType: config.InfluxField, measurement: "checkmarx_data", name: "medium_not_false_postive", value: i.checkmarx_data.fields.medium_not_false_postive}, 135 {valType: config.InfluxField, measurement: "checkmarx_data", name: "medium_not_exploitable", value: i.checkmarx_data.fields.medium_not_exploitable}, 136 {valType: config.InfluxField, measurement: "checkmarx_data", name: "medium_confirmed", value: i.checkmarx_data.fields.medium_confirmed}, 137 {valType: config.InfluxField, measurement: "checkmarx_data", name: "medium_urgent", value: i.checkmarx_data.fields.medium_urgent}, 138 {valType: config.InfluxField, measurement: "checkmarx_data", name: "medium_proposed_not_exploitable", value: i.checkmarx_data.fields.medium_proposed_not_exploitable}, 139 {valType: config.InfluxField, measurement: "checkmarx_data", name: "medium_to_verify", value: i.checkmarx_data.fields.medium_to_verify}, 140 {valType: config.InfluxField, measurement: "checkmarx_data", name: "low_issues", value: i.checkmarx_data.fields.low_issues}, 141 {valType: config.InfluxField, measurement: "checkmarx_data", name: "low_not_false_postive", value: i.checkmarx_data.fields.low_not_false_postive}, 142 {valType: config.InfluxField, measurement: "checkmarx_data", name: "low_not_exploitable", value: i.checkmarx_data.fields.low_not_exploitable}, 143 {valType: config.InfluxField, measurement: "checkmarx_data", name: "low_confirmed", value: i.checkmarx_data.fields.low_confirmed}, 144 {valType: config.InfluxField, measurement: "checkmarx_data", name: "low_urgent", value: i.checkmarx_data.fields.low_urgent}, 145 {valType: config.InfluxField, measurement: "checkmarx_data", name: "low_proposed_not_exploitable", value: i.checkmarx_data.fields.low_proposed_not_exploitable}, 146 {valType: config.InfluxField, measurement: "checkmarx_data", name: "low_to_verify", value: i.checkmarx_data.fields.low_to_verify}, 147 {valType: config.InfluxField, measurement: "checkmarx_data", name: "information_issues", value: i.checkmarx_data.fields.information_issues}, 148 {valType: config.InfluxField, measurement: "checkmarx_data", name: "information_not_false_postive", value: i.checkmarx_data.fields.information_not_false_postive}, 149 {valType: config.InfluxField, measurement: "checkmarx_data", name: "information_not_exploitable", value: i.checkmarx_data.fields.information_not_exploitable}, 150 {valType: config.InfluxField, measurement: "checkmarx_data", name: "information_confirmed", value: i.checkmarx_data.fields.information_confirmed}, 151 {valType: config.InfluxField, measurement: "checkmarx_data", name: "information_urgent", value: i.checkmarx_data.fields.information_urgent}, 152 {valType: config.InfluxField, measurement: "checkmarx_data", name: "information_proposed_not_exploitable", value: i.checkmarx_data.fields.information_proposed_not_exploitable}, 153 {valType: config.InfluxField, measurement: "checkmarx_data", name: "information_to_verify", value: i.checkmarx_data.fields.information_to_verify}, 154 {valType: config.InfluxField, measurement: "checkmarx_data", name: "lines_of_code_scanned", value: i.checkmarx_data.fields.lines_of_code_scanned}, 155 {valType: config.InfluxField, measurement: "checkmarx_data", name: "files_scanned", value: i.checkmarx_data.fields.files_scanned}, 156 {valType: config.InfluxField, measurement: "checkmarx_data", name: "initiator_name", value: i.checkmarx_data.fields.initiator_name}, 157 {valType: config.InfluxField, measurement: "checkmarx_data", name: "owner", value: i.checkmarx_data.fields.owner}, 158 {valType: config.InfluxField, measurement: "checkmarx_data", name: "scan_id", value: i.checkmarx_data.fields.scan_id}, 159 {valType: config.InfluxField, measurement: "checkmarx_data", name: "project_id", value: i.checkmarx_data.fields.project_id}, 160 {valType: config.InfluxField, measurement: "checkmarx_data", name: "projectName", value: i.checkmarx_data.fields.projectName}, 161 {valType: config.InfluxField, measurement: "checkmarx_data", name: "team", value: i.checkmarx_data.fields.team}, 162 {valType: config.InfluxField, measurement: "checkmarx_data", name: "team_full_path_on_report_date", value: i.checkmarx_data.fields.team_full_path_on_report_date}, 163 {valType: config.InfluxField, measurement: "checkmarx_data", name: "scan_start", value: i.checkmarx_data.fields.scan_start}, 164 {valType: config.InfluxField, measurement: "checkmarx_data", name: "scan_time", value: i.checkmarx_data.fields.scan_time}, 165 {valType: config.InfluxField, measurement: "checkmarx_data", name: "checkmarx_version", value: i.checkmarx_data.fields.checkmarx_version}, 166 {valType: config.InfluxField, measurement: "checkmarx_data", name: "scan_type", value: i.checkmarx_data.fields.scan_type}, 167 {valType: config.InfluxField, measurement: "checkmarx_data", name: "preset", value: i.checkmarx_data.fields.preset}, 168 {valType: config.InfluxField, measurement: "checkmarx_data", name: "deep_link", value: i.checkmarx_data.fields.deep_link}, 169 {valType: config.InfluxField, measurement: "checkmarx_data", name: "report_creation_time", value: i.checkmarx_data.fields.report_creation_time}, 170 } 171 172 errCount := 0 173 for _, metric := range measurementContent { 174 err := piperenv.SetResourceParameter(path, resourceName, filepath.Join(metric.measurement, fmt.Sprintf("%vs", metric.valType), metric.name), metric.value) 175 if err != nil { 176 log.Entry().WithError(err).Error("Error persisting influx environment.") 177 errCount++ 178 } 179 } 180 if errCount > 0 { 181 log.Entry().Error("failed to persist Influx environment") 182 } 183 } 184 185 type checkmarxExecuteScanReports struct { 186 } 187 188 func (p *checkmarxExecuteScanReports) persist(stepConfig checkmarxExecuteScanOptions, gcpJsonKeyFilePath string, gcsBucketId string, gcsFolderPath string, gcsSubFolder string) { 189 if gcsBucketId == "" { 190 log.Entry().Info("persisting reports to GCS is disabled, because gcsBucketId is empty") 191 return 192 } 193 log.Entry().Info("Uploading reports to Google Cloud Storage...") 194 content := []gcs.ReportOutputParam{ 195 {FilePattern: "**/piper_checkmarx_report.html", ParamRef: "", StepResultType: "checkmarx"}, 196 {FilePattern: "**/CxSASTResults_*.xml", ParamRef: "", StepResultType: "checkmarx"}, 197 {FilePattern: "**/ScanReport.*", ParamRef: "", StepResultType: "checkmarx"}, 198 {FilePattern: "**/toolrun_checkmarx_*.json", ParamRef: "", StepResultType: "checkmarx"}, 199 } 200 envVars := []gcs.EnvVar{ 201 {Name: "GOOGLE_APPLICATION_CREDENTIALS", Value: gcpJsonKeyFilePath, Modified: false}, 202 } 203 gcsClient, err := gcs.NewClient(gcs.WithEnvVars(envVars)) 204 if err != nil { 205 log.Entry().Errorf("creation of GCS client failed: %v", err) 206 return 207 } 208 defer gcsClient.Close() 209 structVal := reflect.ValueOf(&stepConfig).Elem() 210 inputParameters := map[string]string{} 211 for i := 0; i < structVal.NumField(); i++ { 212 field := structVal.Type().Field(i) 213 if field.Type.String() == "string" { 214 paramName := strings.Split(field.Tag.Get("json"), ",") 215 paramValue, _ := structVal.Field(i).Interface().(string) 216 inputParameters[paramName[0]] = paramValue 217 } 218 } 219 if err := gcs.PersistReportsToGCS(gcsClient, content, inputParameters, gcsFolderPath, gcsBucketId, gcsSubFolder, doublestar.Glob, os.Stat); err != nil { 220 log.Entry().Errorf("failed to persist reports: %v", err) 221 } 222 } 223 224 // CheckmarxExecuteScanCommand Checkmarx is the recommended tool for security scans of JavaScript, iOS, Swift and Ruby code. 225 func CheckmarxExecuteScanCommand() *cobra.Command { 226 const STEP_NAME = "checkmarxExecuteScan" 227 228 metadata := checkmarxExecuteScanMetadata() 229 var stepConfig checkmarxExecuteScanOptions 230 var startTime time.Time 231 var influx checkmarxExecuteScanInflux 232 var reports checkmarxExecuteScanReports 233 var logCollector *log.CollectorHook 234 var splunkClient *splunk.Splunk 235 telemetryClient := &telemetry.Telemetry{} 236 237 var createCheckmarxExecuteScanCmd = &cobra.Command{ 238 Use: STEP_NAME, 239 Short: "Checkmarx is the recommended tool for security scans of JavaScript, iOS, Swift and Ruby code.", 240 Long: `Checkmarx is a Static Application Security Testing (SAST) tool to analyze i.e. Java- or TypeScript, Swift, Golang, Ruby code, 241 and many other programming languages for security flaws based on a set of provided rules/queries that can be customized and extended. 242 243 This step by default enforces a specific audit baseline for findings and therefore ensures that: 244 245 * No 'To Verify' High and Medium issues exist in your project 246 * Total number of High and Medium 'Confirmed' or 'Urgent' issues is zero 247 * 10% of all Low issues are 'Confirmed' or 'Not Exploitable' 248 249 You can adapt above thresholds specifically using the provided configuration parameters and i.e. check for ` + "`" + `absolute` + "`" + ` 250 thresholds instead of ` + "`" + `percentage` + "`" + ` whereas we strongly recommend you to stay with the defaults provided.`, 251 PreRunE: func(cmd *cobra.Command, _ []string) error { 252 startTime = time.Now() 253 log.SetStepName(STEP_NAME) 254 log.SetVerbose(GeneralConfig.Verbose) 255 256 GeneralConfig.GitHubAccessTokens = ResolveAccessTokens(GeneralConfig.GitHubTokens) 257 258 path, _ := os.Getwd() 259 fatalHook := &log.FatalHook{CorrelationID: GeneralConfig.CorrelationID, Path: path} 260 log.RegisterHook(fatalHook) 261 262 err := PrepareConfig(cmd, &metadata, STEP_NAME, &stepConfig, config.OpenPiperFile) 263 if err != nil { 264 log.SetErrorCategory(log.ErrorConfiguration) 265 return err 266 } 267 log.RegisterSecret(stepConfig.GithubToken) 268 log.RegisterSecret(stepConfig.Password) 269 log.RegisterSecret(stepConfig.Username) 270 271 if len(GeneralConfig.HookConfig.SentryConfig.Dsn) > 0 { 272 sentryHook := log.NewSentryHook(GeneralConfig.HookConfig.SentryConfig.Dsn, GeneralConfig.CorrelationID) 273 log.RegisterHook(&sentryHook) 274 } 275 276 if len(GeneralConfig.HookConfig.SplunkConfig.Dsn) > 0 { 277 splunkClient = &splunk.Splunk{} 278 logCollector = &log.CollectorHook{CorrelationID: GeneralConfig.CorrelationID} 279 log.RegisterHook(logCollector) 280 } 281 282 validation, err := validation.New(validation.WithJSONNamesForStructFields(), validation.WithPredefinedErrorMessages()) 283 if err != nil { 284 return err 285 } 286 if err = validation.ValidateStruct(stepConfig); err != nil { 287 log.SetErrorCategory(log.ErrorConfiguration) 288 return err 289 } 290 291 return nil 292 }, 293 Run: func(_ *cobra.Command, _ []string) { 294 stepTelemetryData := telemetry.CustomData{} 295 stepTelemetryData.ErrorCode = "1" 296 handler := func() { 297 influx.persist(GeneralConfig.EnvRootPath, "influx") 298 reports.persist(stepConfig, GeneralConfig.GCPJsonKeyFilePath, GeneralConfig.GCSBucketId, GeneralConfig.GCSFolderPath, GeneralConfig.GCSSubFolder) 299 config.RemoveVaultSecretFiles() 300 stepTelemetryData.Duration = fmt.Sprintf("%v", time.Since(startTime).Milliseconds()) 301 stepTelemetryData.ErrorCategory = log.GetErrorCategory().String() 302 stepTelemetryData.PiperCommitHash = GitCommit 303 telemetryClient.SetData(&stepTelemetryData) 304 telemetryClient.Send() 305 if len(GeneralConfig.HookConfig.SplunkConfig.Dsn) > 0 { 306 splunkClient.Send(telemetryClient.GetData(), logCollector) 307 } 308 } 309 log.DeferExitHandler(handler) 310 defer handler() 311 telemetryClient.Initialize(GeneralConfig.NoTelemetry, STEP_NAME) 312 if len(GeneralConfig.HookConfig.SplunkConfig.Dsn) > 0 { 313 splunkClient.Initialize(GeneralConfig.CorrelationID, 314 GeneralConfig.HookConfig.SplunkConfig.Dsn, 315 GeneralConfig.HookConfig.SplunkConfig.Token, 316 GeneralConfig.HookConfig.SplunkConfig.Index, 317 GeneralConfig.HookConfig.SplunkConfig.SendLogs) 318 } 319 checkmarxExecuteScan(stepConfig, &stepTelemetryData, &influx) 320 stepTelemetryData.ErrorCode = "0" 321 log.Entry().Info("SUCCESS") 322 }, 323 } 324 325 addCheckmarxExecuteScanFlags(createCheckmarxExecuteScanCmd, &stepConfig) 326 return createCheckmarxExecuteScanCmd 327 } 328 329 func addCheckmarxExecuteScanFlags(cmd *cobra.Command, stepConfig *checkmarxExecuteScanOptions) { 330 cmd.Flags().StringSliceVar(&stepConfig.Assignees, "assignees", []string{``}, "Defines the assignees for the Github Issue created/updated with the results of the scan as a list of login names.") 331 cmd.Flags().BoolVar(&stepConfig.AvoidDuplicateProjectScans, "avoidDuplicateProjectScans", true, "Whether duplicate scans of the same project state shall be avoided or not") 332 cmd.Flags().StringVar(&stepConfig.FilterPattern, "filterPattern", `!**/node_modules/**, !**/.xmake/**, !**/*_test.go, !**/vendor/**/*.go, **/*.html, **/*.xml, **/*.go, **/*.py, **/*.js, **/*.scala, **/*.ts`, "The filter pattern used to zip the files relevant for scanning, patterns can be negated by setting an exclamation mark in front i.e. `!test/*.js` would avoid adding any javascript files located in the test directory") 333 cmd.Flags().StringVar(&stepConfig.FullScanCycle, "fullScanCycle", `5`, "Indicates how often a full scan should happen between the incremental scans when activated") 334 cmd.Flags().BoolVar(&stepConfig.FullScansScheduled, "fullScansScheduled", true, "Whether full scans are to be scheduled or not. Should be used in relation with `incremental` and `fullScanCycle`") 335 cmd.Flags().BoolVar(&stepConfig.GeneratePdfReport, "generatePdfReport", true, "Whether to generate a PDF report of the analysis results or not") 336 cmd.Flags().StringVar(&stepConfig.GithubAPIURL, "githubApiUrl", `https://api.github.com`, "Set the GitHub API URL.") 337 cmd.Flags().StringVar(&stepConfig.GithubToken, "githubToken", os.Getenv("PIPER_githubToken"), "GitHub personal access token as per https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line") 338 cmd.Flags().BoolVar(&stepConfig.Incremental, "incremental", true, "Whether incremental scans are to be applied which optimizes the scan time but might reduce detection capabilities. Therefore full scans are still required from time to time and should be scheduled via `fullScansScheduled` and `fullScanCycle`") 339 cmd.Flags().IntVar(&stepConfig.MaxRetries, "maxRetries", 3, "Maximum number of HTTP request retries upon intermittend connetion interrupts") 340 cmd.Flags().StringVar(&stepConfig.Owner, "owner", os.Getenv("PIPER_owner"), "Set the GitHub organization.") 341 cmd.Flags().StringVar(&stepConfig.Password, "password", os.Getenv("PIPER_password"), "The password to authenticate") 342 cmd.Flags().StringVar(&stepConfig.Preset, "preset", os.Getenv("PIPER_preset"), "The preset to use for scanning, if not set explicitly the step will attempt to look up the project's setting based on the availability of `checkmarxCredentialsId`") 343 cmd.Flags().StringVar(&stepConfig.ProjectName, "projectName", os.Getenv("PIPER_projectName"), "The name of the Checkmarx project to scan into") 344 cmd.Flags().StringVar(&stepConfig.PullRequestName, "pullRequestName", os.Getenv("PIPER_pullRequestName"), "Used to supply the name for the newly created PR project branch when being used in pull request scenarios") 345 cmd.Flags().StringVar(&stepConfig.Repository, "repository", os.Getenv("PIPER_repository"), "Set the GitHub repository.") 346 cmd.Flags().StringVar(&stepConfig.ServerURL, "serverUrl", os.Getenv("PIPER_serverUrl"), "The URL pointing to the root of the Checkmarx server to be used") 347 cmd.Flags().StringVar(&stepConfig.SourceEncoding, "sourceEncoding", `1`, "The source encoding to be used, if not set explicitly the project's default will be used") 348 cmd.Flags().StringVar(&stepConfig.TeamID, "teamId", os.Getenv("PIPER_teamId"), "The group ID related to your team which can be obtained via the Pipeline Syntax plugin as described in the `Details` section") 349 cmd.Flags().StringVar(&stepConfig.TeamName, "teamName", os.Getenv("PIPER_teamName"), "The full name of the team to assign newly created projects to which is preferred to teamId") 350 cmd.Flags().StringVar(&stepConfig.Username, "username", os.Getenv("PIPER_username"), "The username to authenticate") 351 cmd.Flags().BoolVar(&stepConfig.VerifyOnly, "verifyOnly", false, "Whether the step shall only apply verification checks or whether it does a full scan and check cycle") 352 cmd.Flags().BoolVar(&stepConfig.VulnerabilityThresholdEnabled, "vulnerabilityThresholdEnabled", true, "Whether the thresholds are enabled or not. If enabled the build will be set to `vulnerabilityThresholdResult` in case a specific threshold value is exceeded") 353 cmd.Flags().IntVar(&stepConfig.VulnerabilityThresholdHigh, "vulnerabilityThresholdHigh", 100, "The specific threshold for high severity findings") 354 cmd.Flags().IntVar(&stepConfig.VulnerabilityThresholdLow, "vulnerabilityThresholdLow", 10, "The specific threshold for low severity findings") 355 cmd.Flags().IntVar(&stepConfig.VulnerabilityThresholdMedium, "vulnerabilityThresholdMedium", 100, "The specific threshold for medium severity findings") 356 cmd.Flags().StringVar(&stepConfig.VulnerabilityThresholdResult, "vulnerabilityThresholdResult", `FAILURE`, "The result of the build in case thresholds are enabled and exceeded") 357 cmd.Flags().StringVar(&stepConfig.VulnerabilityThresholdUnit, "vulnerabilityThresholdUnit", `percentage`, "The unit for the threshold to apply.") 358 cmd.Flags().BoolVar(&stepConfig.IsOptimizedAndScheduled, "isOptimizedAndScheduled", false, "Whether the pipeline runs in optimized mode and the current execution is a scheduled one") 359 cmd.Flags().BoolVar(&stepConfig.CreateResultIssue, "createResultIssue", false, "Activate creation of a result issue in GitHub.") 360 cmd.Flags().BoolVar(&stepConfig.ConvertToSarif, "convertToSarif", false, "[BETA] Convert the Checkmarx XML (Cxxml) scan results to the open SARIF standard. Uploaded through Cumulus later on.") 361 362 cmd.MarkFlagRequired("password") 363 cmd.MarkFlagRequired("projectName") 364 cmd.MarkFlagRequired("serverUrl") 365 cmd.MarkFlagRequired("username") 366 } 367 368 // retrieve step metadata 369 func checkmarxExecuteScanMetadata() config.StepData { 370 var theMetaData = config.StepData{ 371 Metadata: config.StepMetadata{ 372 Name: "checkmarxExecuteScan", 373 Aliases: []config.Alias{}, 374 Description: "Checkmarx is the recommended tool for security scans of JavaScript, iOS, Swift and Ruby code.", 375 }, 376 Spec: config.StepSpec{ 377 Inputs: config.StepInputs{ 378 Secrets: []config.StepSecrets{ 379 {Name: "checkmarxCredentialsId", Description: "Jenkins 'Username with password' credentials ID containing username and password to communicate with the Checkmarx backend.", Type: "jenkins"}, 380 }, 381 Resources: []config.StepResources{ 382 {Name: "checkmarx", Type: "stash"}, 383 }, 384 Parameters: []config.StepParameters{ 385 { 386 Name: "assignees", 387 ResourceRef: []config.ResourceReference{}, 388 Scope: []string{"PARAMETERS", "STAGES", "STEPS"}, 389 Type: "[]string", 390 Mandatory: false, 391 Aliases: []config.Alias{}, 392 Default: []string{``}, 393 }, 394 { 395 Name: "avoidDuplicateProjectScans", 396 ResourceRef: []config.ResourceReference{}, 397 Scope: []string{"PARAMETERS", "STAGES", "STEPS"}, 398 Type: "bool", 399 Mandatory: false, 400 Aliases: []config.Alias{}, 401 Default: true, 402 }, 403 { 404 Name: "filterPattern", 405 ResourceRef: []config.ResourceReference{}, 406 Scope: []string{"PARAMETERS", "STAGES", "STEPS"}, 407 Type: "string", 408 Mandatory: false, 409 Aliases: []config.Alias{}, 410 Default: `!**/node_modules/**, !**/.xmake/**, !**/*_test.go, !**/vendor/**/*.go, **/*.html, **/*.xml, **/*.go, **/*.py, **/*.js, **/*.scala, **/*.ts`, 411 }, 412 { 413 Name: "fullScanCycle", 414 ResourceRef: []config.ResourceReference{}, 415 Scope: []string{"PARAMETERS", "STAGES", "STEPS"}, 416 Type: "string", 417 Mandatory: false, 418 Aliases: []config.Alias{}, 419 Default: `5`, 420 }, 421 { 422 Name: "fullScansScheduled", 423 ResourceRef: []config.ResourceReference{}, 424 Scope: []string{"PARAMETERS", "STAGES", "STEPS"}, 425 Type: "bool", 426 Mandatory: false, 427 Aliases: []config.Alias{}, 428 Default: true, 429 }, 430 { 431 Name: "generatePdfReport", 432 ResourceRef: []config.ResourceReference{}, 433 Scope: []string{"PARAMETERS", "STAGES", "STEPS"}, 434 Type: "bool", 435 Mandatory: false, 436 Aliases: []config.Alias{}, 437 Default: true, 438 }, 439 { 440 Name: "githubApiUrl", 441 ResourceRef: []config.ResourceReference{}, 442 Scope: []string{"GENERAL", "PARAMETERS", "STAGES", "STEPS"}, 443 Type: "string", 444 Mandatory: false, 445 Aliases: []config.Alias{}, 446 Default: `https://api.github.com`, 447 }, 448 { 449 Name: "githubToken", 450 ResourceRef: []config.ResourceReference{ 451 { 452 Name: "githubTokenCredentialsId", 453 Type: "secret", 454 }, 455 456 { 457 Name: "githubVaultSecretName", 458 Type: "vaultSecret", 459 Default: "github", 460 }, 461 }, 462 Scope: []string{"GENERAL", "PARAMETERS", "STAGES", "STEPS"}, 463 Type: "string", 464 Mandatory: false, 465 Aliases: []config.Alias{{Name: "access_token"}}, 466 Default: os.Getenv("PIPER_githubToken"), 467 }, 468 { 469 Name: "incremental", 470 ResourceRef: []config.ResourceReference{}, 471 Scope: []string{"PARAMETERS", "STAGES", "STEPS"}, 472 Type: "bool", 473 Mandatory: false, 474 Aliases: []config.Alias{}, 475 Default: true, 476 }, 477 { 478 Name: "maxRetries", 479 ResourceRef: []config.ResourceReference{}, 480 Scope: []string{"PARAMETERS", "STAGES", "STEPS"}, 481 Type: "int", 482 Mandatory: false, 483 Aliases: []config.Alias{}, 484 Default: 3, 485 }, 486 { 487 Name: "owner", 488 ResourceRef: []config.ResourceReference{ 489 { 490 Name: "commonPipelineEnvironment", 491 Param: "github/owner", 492 }, 493 }, 494 Scope: []string{"GENERAL", "PARAMETERS", "STAGES", "STEPS"}, 495 Type: "string", 496 Mandatory: false, 497 Aliases: []config.Alias{{Name: "githubOrg"}}, 498 Default: os.Getenv("PIPER_owner"), 499 }, 500 { 501 Name: "password", 502 ResourceRef: []config.ResourceReference{ 503 { 504 Name: "checkmarxCredentialsId", 505 Param: "password", 506 Type: "secret", 507 }, 508 509 { 510 Name: "checkmarxVaultSecretName", 511 Type: "vaultSecret", 512 Default: "checkmarx", 513 }, 514 }, 515 Scope: []string{"PARAMETERS", "STAGES", "STEPS"}, 516 Type: "string", 517 Mandatory: true, 518 Aliases: []config.Alias{}, 519 Default: os.Getenv("PIPER_password"), 520 }, 521 { 522 Name: "preset", 523 ResourceRef: []config.ResourceReference{}, 524 Scope: []string{"PARAMETERS", "STAGES", "STEPS"}, 525 Type: "string", 526 Mandatory: false, 527 Aliases: []config.Alias{}, 528 Default: os.Getenv("PIPER_preset"), 529 }, 530 { 531 Name: "projectName", 532 ResourceRef: []config.ResourceReference{}, 533 Scope: []string{"PARAMETERS", "STAGES", "STEPS"}, 534 Type: "string", 535 Mandatory: true, 536 Aliases: []config.Alias{{Name: "checkmarxProject"}, {Name: "checkMarxProjectName", Deprecated: true}}, 537 Default: os.Getenv("PIPER_projectName"), 538 }, 539 { 540 Name: "pullRequestName", 541 ResourceRef: []config.ResourceReference{}, 542 Scope: []string{"PARAMETERS", "STAGES", "STEPS"}, 543 Type: "string", 544 Mandatory: false, 545 Aliases: []config.Alias{}, 546 Default: os.Getenv("PIPER_pullRequestName"), 547 }, 548 { 549 Name: "repository", 550 ResourceRef: []config.ResourceReference{ 551 { 552 Name: "commonPipelineEnvironment", 553 Param: "github/repository", 554 }, 555 }, 556 Scope: []string{"GENERAL", "PARAMETERS", "STAGES", "STEPS"}, 557 Type: "string", 558 Mandatory: false, 559 Aliases: []config.Alias{{Name: "githubRepo"}}, 560 Default: os.Getenv("PIPER_repository"), 561 }, 562 { 563 Name: "serverUrl", 564 ResourceRef: []config.ResourceReference{}, 565 Scope: []string{"GENERAL", "PARAMETERS", "STAGES", "STEPS"}, 566 Type: "string", 567 Mandatory: true, 568 Aliases: []config.Alias{{Name: "checkmarxServerUrl"}}, 569 Default: os.Getenv("PIPER_serverUrl"), 570 }, 571 { 572 Name: "sourceEncoding", 573 ResourceRef: []config.ResourceReference{}, 574 Scope: []string{"PARAMETERS", "STAGES", "STEPS"}, 575 Type: "string", 576 Mandatory: false, 577 Aliases: []config.Alias{}, 578 Default: `1`, 579 }, 580 { 581 Name: "teamId", 582 ResourceRef: []config.ResourceReference{}, 583 Scope: []string{"PARAMETERS", "STAGES", "STEPS"}, 584 Type: "string", 585 Mandatory: false, 586 Aliases: []config.Alias{{Name: "checkmarxGroupId"}, {Name: "groupId", Deprecated: true}}, 587 Default: os.Getenv("PIPER_teamId"), 588 }, 589 { 590 Name: "teamName", 591 ResourceRef: []config.ResourceReference{}, 592 Scope: []string{"PARAMETERS", "STAGES", "STEPS"}, 593 Type: "string", 594 Mandatory: false, 595 Aliases: []config.Alias{}, 596 Default: os.Getenv("PIPER_teamName"), 597 }, 598 { 599 Name: "username", 600 ResourceRef: []config.ResourceReference{ 601 { 602 Name: "checkmarxCredentialsId", 603 Param: "username", 604 Type: "secret", 605 }, 606 607 { 608 Name: "checkmarxVaultSecretName", 609 Type: "vaultSecret", 610 Default: "checkmarx", 611 }, 612 }, 613 Scope: []string{"PARAMETERS", "STAGES", "STEPS"}, 614 Type: "string", 615 Mandatory: true, 616 Aliases: []config.Alias{}, 617 Default: os.Getenv("PIPER_username"), 618 }, 619 { 620 Name: "verifyOnly", 621 ResourceRef: []config.ResourceReference{}, 622 Scope: []string{"PARAMETERS", "STAGES", "STEPS"}, 623 Type: "bool", 624 Mandatory: false, 625 Aliases: []config.Alias{}, 626 Default: false, 627 }, 628 { 629 Name: "vulnerabilityThresholdEnabled", 630 ResourceRef: []config.ResourceReference{}, 631 Scope: []string{"PARAMETERS", "STAGES", "STEPS"}, 632 Type: "bool", 633 Mandatory: false, 634 Aliases: []config.Alias{}, 635 Default: true, 636 }, 637 { 638 Name: "vulnerabilityThresholdHigh", 639 ResourceRef: []config.ResourceReference{}, 640 Scope: []string{"PARAMETERS", "STAGES", "STEPS"}, 641 Type: "int", 642 Mandatory: false, 643 Aliases: []config.Alias{}, 644 Default: 100, 645 }, 646 { 647 Name: "vulnerabilityThresholdLow", 648 ResourceRef: []config.ResourceReference{}, 649 Scope: []string{"PARAMETERS", "STAGES", "STEPS"}, 650 Type: "int", 651 Mandatory: false, 652 Aliases: []config.Alias{}, 653 Default: 10, 654 }, 655 { 656 Name: "vulnerabilityThresholdMedium", 657 ResourceRef: []config.ResourceReference{}, 658 Scope: []string{"PARAMETERS", "STAGES", "STEPS"}, 659 Type: "int", 660 Mandatory: false, 661 Aliases: []config.Alias{}, 662 Default: 100, 663 }, 664 { 665 Name: "vulnerabilityThresholdResult", 666 ResourceRef: []config.ResourceReference{}, 667 Scope: []string{"PARAMETERS", "STAGES", "STEPS"}, 668 Type: "string", 669 Mandatory: false, 670 Aliases: []config.Alias{}, 671 Default: `FAILURE`, 672 }, 673 { 674 Name: "vulnerabilityThresholdUnit", 675 ResourceRef: []config.ResourceReference{}, 676 Scope: []string{"PARAMETERS", "STAGES", "STEPS"}, 677 Type: "string", 678 Mandatory: false, 679 Aliases: []config.Alias{}, 680 Default: `percentage`, 681 }, 682 { 683 Name: "isOptimizedAndScheduled", 684 ResourceRef: []config.ResourceReference{ 685 { 686 Name: "commonPipelineEnvironment", 687 Param: "custom/isOptimizedAndScheduled", 688 }, 689 }, 690 Scope: []string{"PARAMETERS"}, 691 Type: "bool", 692 Mandatory: false, 693 Aliases: []config.Alias{}, 694 Default: false, 695 }, 696 { 697 Name: "createResultIssue", 698 ResourceRef: []config.ResourceReference{ 699 { 700 Name: "commonPipelineEnvironment", 701 Param: "custom/isOptimizedAndScheduled", 702 }, 703 }, 704 Scope: []string{"GENERAL", "PARAMETERS", "STAGES", "STEPS"}, 705 Type: "bool", 706 Mandatory: false, 707 Aliases: []config.Alias{}, 708 Default: false, 709 }, 710 { 711 Name: "convertToSarif", 712 ResourceRef: []config.ResourceReference{}, 713 Scope: []string{"PARAMETERS", "STAGES", "STEPS"}, 714 Type: "bool", 715 Mandatory: false, 716 Aliases: []config.Alias{}, 717 Default: false, 718 }, 719 }, 720 }, 721 Outputs: config.StepOutputs{ 722 Resources: []config.StepResources{ 723 { 724 Name: "influx", 725 Type: "influx", 726 Parameters: []map[string]interface{}{ 727 {"name": "step_data", "fields": []map[string]string{{"name": "checkmarx"}}}, 728 {"name": "checkmarx_data", "fields": []map[string]string{{"name": "high_issues"}, {"name": "high_not_false_postive"}, {"name": "high_not_exploitable"}, {"name": "high_confirmed"}, {"name": "high_urgent"}, {"name": "high_proposed_not_exploitable"}, {"name": "high_to_verify"}, {"name": "medium_issues"}, {"name": "medium_not_false_postive"}, {"name": "medium_not_exploitable"}, {"name": "medium_confirmed"}, {"name": "medium_urgent"}, {"name": "medium_proposed_not_exploitable"}, {"name": "medium_to_verify"}, {"name": "low_issues"}, {"name": "low_not_false_postive"}, {"name": "low_not_exploitable"}, {"name": "low_confirmed"}, {"name": "low_urgent"}, {"name": "low_proposed_not_exploitable"}, {"name": "low_to_verify"}, {"name": "information_issues"}, {"name": "information_not_false_postive"}, {"name": "information_not_exploitable"}, {"name": "information_confirmed"}, {"name": "information_urgent"}, {"name": "information_proposed_not_exploitable"}, {"name": "information_to_verify"}, {"name": "lines_of_code_scanned"}, {"name": "files_scanned"}, {"name": "initiator_name"}, {"name": "owner"}, {"name": "scan_id"}, {"name": "project_id"}, {"name": "projectName"}, {"name": "team"}, {"name": "team_full_path_on_report_date"}, {"name": "scan_start"}, {"name": "scan_time"}, {"name": "checkmarx_version"}, {"name": "scan_type"}, {"name": "preset"}, {"name": "deep_link"}, {"name": "report_creation_time"}}}, 729 }, 730 }, 731 { 732 Name: "reports", 733 Type: "reports", 734 Parameters: []map[string]interface{}{ 735 {"filePattern": "**/piper_checkmarx_report.html", "type": "checkmarx"}, 736 {"filePattern": "**/CxSASTResults_*.xml", "type": "checkmarx"}, 737 {"filePattern": "**/ScanReport.*", "type": "checkmarx"}, 738 {"filePattern": "**/toolrun_checkmarx_*.json", "type": "checkmarx"}, 739 }, 740 }, 741 }, 742 }, 743 }, 744 } 745 return theMetaData 746 }