github.com/xgoffin/jenkins-library@v1.154.0/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, "Whether the step creates a GitHub issue containing the scan results in the originating repo. Since optimized pipelines are headless the creation is implicitly activated for schedules runs.")
   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/optimizedAndScheduled",
   702  							},
   703  						},
   704  						Scope:     []string{"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  }