github.com/xgoffin/jenkins-library@v1.154.0/cmd/protecodeExecuteScan_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 protecodeExecuteScanOptions struct {
    25  	ExcludeCVEs                 string `json:"excludeCVEs,omitempty"`
    26  	FailOnSevereVulnerabilities bool   `json:"failOnSevereVulnerabilities,omitempty"`
    27  	ScanImage                   string `json:"scanImage,omitempty"`
    28  	DockerRegistryURL           string `json:"dockerRegistryUrl,omitempty"`
    29  	DockerConfigJSON            string `json:"dockerConfigJSON,omitempty"`
    30  	CleanupMode                 string `json:"cleanupMode,omitempty" validate:"possible-values=none binary complete"`
    31  	FilePath                    string `json:"filePath,omitempty"`
    32  	IncludeLayers               bool   `json:"includeLayers,omitempty"`
    33  	TimeoutMinutes              string `json:"timeoutMinutes,omitempty"`
    34  	ServerURL                   string `json:"serverUrl,omitempty"`
    35  	ReportFileName              string `json:"reportFileName,omitempty"`
    36  	FetchURL                    string `json:"fetchUrl,omitempty"`
    37  	Group                       string `json:"group,omitempty"`
    38  	VerifyOnly                  bool   `json:"verifyOnly,omitempty"`
    39  	ReplaceProductID            int    `json:"replaceProductId,omitempty"`
    40  	Username                    string `json:"username,omitempty"`
    41  	Password                    string `json:"password,omitempty"`
    42  	Version                     string `json:"version,omitempty"`
    43  	CustomScanVersion           string `json:"customScanVersion,omitempty"`
    44  	VersioningModel             string `json:"versioningModel,omitempty" validate:"possible-values=major major-minor semantic full"`
    45  	PullRequestName             string `json:"pullRequestName,omitempty"`
    46  }
    47  
    48  type protecodeExecuteScanInflux struct {
    49  	step_data struct {
    50  		fields struct {
    51  			protecode bool
    52  		}
    53  		tags struct {
    54  		}
    55  	}
    56  	protecode_data struct {
    57  		fields struct {
    58  			excluded_vulnerabilities   int
    59  			historical_vulnerabilities int
    60  			major_vulnerabilities      int
    61  			minor_vulnerabilities      int
    62  			triaged_vulnerabilities    int
    63  			vulnerabilities            int
    64  		}
    65  		tags struct {
    66  		}
    67  	}
    68  }
    69  
    70  func (i *protecodeExecuteScanInflux) persist(path, resourceName string) {
    71  	measurementContent := []struct {
    72  		measurement string
    73  		valType     string
    74  		name        string
    75  		value       interface{}
    76  	}{
    77  		{valType: config.InfluxField, measurement: "step_data", name: "protecode", value: i.step_data.fields.protecode},
    78  		{valType: config.InfluxField, measurement: "protecode_data", name: "excluded_vulnerabilities", value: i.protecode_data.fields.excluded_vulnerabilities},
    79  		{valType: config.InfluxField, measurement: "protecode_data", name: "historical_vulnerabilities", value: i.protecode_data.fields.historical_vulnerabilities},
    80  		{valType: config.InfluxField, measurement: "protecode_data", name: "major_vulnerabilities", value: i.protecode_data.fields.major_vulnerabilities},
    81  		{valType: config.InfluxField, measurement: "protecode_data", name: "minor_vulnerabilities", value: i.protecode_data.fields.minor_vulnerabilities},
    82  		{valType: config.InfluxField, measurement: "protecode_data", name: "triaged_vulnerabilities", value: i.protecode_data.fields.triaged_vulnerabilities},
    83  		{valType: config.InfluxField, measurement: "protecode_data", name: "vulnerabilities", value: i.protecode_data.fields.vulnerabilities},
    84  	}
    85  
    86  	errCount := 0
    87  	for _, metric := range measurementContent {
    88  		err := piperenv.SetResourceParameter(path, resourceName, filepath.Join(metric.measurement, fmt.Sprintf("%vs", metric.valType), metric.name), metric.value)
    89  		if err != nil {
    90  			log.Entry().WithError(err).Error("Error persisting influx environment.")
    91  			errCount++
    92  		}
    93  	}
    94  	if errCount > 0 {
    95  		log.Entry().Error("failed to persist Influx environment")
    96  	}
    97  }
    98  
    99  type protecodeExecuteScanReports struct {
   100  }
   101  
   102  func (p *protecodeExecuteScanReports) persist(stepConfig protecodeExecuteScanOptions, gcpJsonKeyFilePath string, gcsBucketId string, gcsFolderPath string, gcsSubFolder string) {
   103  	if gcsBucketId == "" {
   104  		log.Entry().Info("persisting reports to GCS is disabled, because gcsBucketId is empty")
   105  		return
   106  	}
   107  	log.Entry().Info("Uploading reports to Google Cloud Storage...")
   108  	content := []gcs.ReportOutputParam{
   109  		{FilePattern: "**/toolrun_protecode_*.json", ParamRef: "", StepResultType: "protecode"},
   110  		{FilePattern: "", ParamRef: "reportFileName", StepResultType: "protecode"},
   111  		{FilePattern: "**/protecodeExecuteScan.json", ParamRef: "", StepResultType: "protecode"},
   112  		{FilePattern: "**/protecodescan_vulns.json", ParamRef: "", StepResultType: "protecode"},
   113  	}
   114  	envVars := []gcs.EnvVar{
   115  		{Name: "GOOGLE_APPLICATION_CREDENTIALS", Value: gcpJsonKeyFilePath, Modified: false},
   116  	}
   117  	gcsClient, err := gcs.NewClient(gcs.WithEnvVars(envVars))
   118  	if err != nil {
   119  		log.Entry().Errorf("creation of GCS client failed: %v", err)
   120  		return
   121  	}
   122  	defer gcsClient.Close()
   123  	structVal := reflect.ValueOf(&stepConfig).Elem()
   124  	inputParameters := map[string]string{}
   125  	for i := 0; i < structVal.NumField(); i++ {
   126  		field := structVal.Type().Field(i)
   127  		if field.Type.String() == "string" {
   128  			paramName := strings.Split(field.Tag.Get("json"), ",")
   129  			paramValue, _ := structVal.Field(i).Interface().(string)
   130  			inputParameters[paramName[0]] = paramValue
   131  		}
   132  	}
   133  	if err := gcs.PersistReportsToGCS(gcsClient, content, inputParameters, gcsFolderPath, gcsBucketId, gcsSubFolder, doublestar.Glob, os.Stat); err != nil {
   134  		log.Entry().Errorf("failed to persist reports: %v", err)
   135  	}
   136  }
   137  
   138  // ProtecodeExecuteScanCommand Black Duck Binary Analysis (BDBA), previously known as Protecode is an Open Source Vulnerability Scanner that is capable of scanning binaries. It can be used to scan docker images but is supports many other programming languages especially those of the C family.
   139  func ProtecodeExecuteScanCommand() *cobra.Command {
   140  	const STEP_NAME = "protecodeExecuteScan"
   141  
   142  	metadata := protecodeExecuteScanMetadata()
   143  	var stepConfig protecodeExecuteScanOptions
   144  	var startTime time.Time
   145  	var influx protecodeExecuteScanInflux
   146  	var reports protecodeExecuteScanReports
   147  	var logCollector *log.CollectorHook
   148  	var splunkClient *splunk.Splunk
   149  	telemetryClient := &telemetry.Telemetry{}
   150  
   151  	var createProtecodeExecuteScanCmd = &cobra.Command{
   152  		Use:   STEP_NAME,
   153  		Short: "Black Duck Binary Analysis (BDBA), previously known as Protecode is an Open Source Vulnerability Scanner that is capable of scanning binaries. It can be used to scan docker images but is supports many other programming languages especially those of the C family.",
   154  		Long: `Black Duck Binary Analysis (previously known as Protecode) is an Open Source Vulnerability Scan tool which provides the composition of Open Source components in a product along with Security information (no license info is provided).
   155  BDBA (Protecode) uses a combination of static binary analysis techniques to X-ray the provided software package to identify third-party software components and their exact versions with a high level of confidence. Methods range from simple string matching to proprietary patent-pending techniques.
   156  
   157  !!! hint "Auditing findings (Triaging)"
   158      Triaging is now supported by the BDBA (Protecode) backend and also Piper does consider this information during the analysis of the scan results though product versions are not supported by BDBA (Protecode). Therefore please make sure that the ` + "`" + `fileName` + "`" + ` you are providing does either contain a stable version or that it does not contain one at all. By ensuring that you are able to triage CVEs globally on the upload file's name without affecting any other artifacts scanned in the same BDBA (Protecode) group and as such triaged vulnerabilities will be considered during the next scan and will not fail the build anymore.`,
   159  		PreRunE: func(cmd *cobra.Command, _ []string) error {
   160  			startTime = time.Now()
   161  			log.SetStepName(STEP_NAME)
   162  			log.SetVerbose(GeneralConfig.Verbose)
   163  
   164  			GeneralConfig.GitHubAccessTokens = ResolveAccessTokens(GeneralConfig.GitHubTokens)
   165  
   166  			path, _ := os.Getwd()
   167  			fatalHook := &log.FatalHook{CorrelationID: GeneralConfig.CorrelationID, Path: path}
   168  			log.RegisterHook(fatalHook)
   169  
   170  			err := PrepareConfig(cmd, &metadata, STEP_NAME, &stepConfig, config.OpenPiperFile)
   171  			if err != nil {
   172  				log.SetErrorCategory(log.ErrorConfiguration)
   173  				return err
   174  			}
   175  			log.RegisterSecret(stepConfig.DockerConfigJSON)
   176  			log.RegisterSecret(stepConfig.Username)
   177  			log.RegisterSecret(stepConfig.Password)
   178  
   179  			if len(GeneralConfig.HookConfig.SentryConfig.Dsn) > 0 {
   180  				sentryHook := log.NewSentryHook(GeneralConfig.HookConfig.SentryConfig.Dsn, GeneralConfig.CorrelationID)
   181  				log.RegisterHook(&sentryHook)
   182  			}
   183  
   184  			if len(GeneralConfig.HookConfig.SplunkConfig.Dsn) > 0 {
   185  				splunkClient = &splunk.Splunk{}
   186  				logCollector = &log.CollectorHook{CorrelationID: GeneralConfig.CorrelationID}
   187  				log.RegisterHook(logCollector)
   188  			}
   189  
   190  			validation, err := validation.New(validation.WithJSONNamesForStructFields(), validation.WithPredefinedErrorMessages())
   191  			if err != nil {
   192  				return err
   193  			}
   194  			if err = validation.ValidateStruct(stepConfig); err != nil {
   195  				log.SetErrorCategory(log.ErrorConfiguration)
   196  				return err
   197  			}
   198  
   199  			return nil
   200  		},
   201  		Run: func(_ *cobra.Command, _ []string) {
   202  			stepTelemetryData := telemetry.CustomData{}
   203  			stepTelemetryData.ErrorCode = "1"
   204  			handler := func() {
   205  				influx.persist(GeneralConfig.EnvRootPath, "influx")
   206  				reports.persist(stepConfig, GeneralConfig.GCPJsonKeyFilePath, GeneralConfig.GCSBucketId, GeneralConfig.GCSFolderPath, GeneralConfig.GCSSubFolder)
   207  				config.RemoveVaultSecretFiles()
   208  				stepTelemetryData.Duration = fmt.Sprintf("%v", time.Since(startTime).Milliseconds())
   209  				stepTelemetryData.ErrorCategory = log.GetErrorCategory().String()
   210  				stepTelemetryData.PiperCommitHash = GitCommit
   211  				telemetryClient.SetData(&stepTelemetryData)
   212  				telemetryClient.Send()
   213  				if len(GeneralConfig.HookConfig.SplunkConfig.Dsn) > 0 {
   214  					splunkClient.Send(telemetryClient.GetData(), logCollector)
   215  				}
   216  			}
   217  			log.DeferExitHandler(handler)
   218  			defer handler()
   219  			telemetryClient.Initialize(GeneralConfig.NoTelemetry, STEP_NAME)
   220  			if len(GeneralConfig.HookConfig.SplunkConfig.Dsn) > 0 {
   221  				splunkClient.Initialize(GeneralConfig.CorrelationID,
   222  					GeneralConfig.HookConfig.SplunkConfig.Dsn,
   223  					GeneralConfig.HookConfig.SplunkConfig.Token,
   224  					GeneralConfig.HookConfig.SplunkConfig.Index,
   225  					GeneralConfig.HookConfig.SplunkConfig.SendLogs)
   226  			}
   227  			protecodeExecuteScan(stepConfig, &stepTelemetryData, &influx)
   228  			stepTelemetryData.ErrorCode = "0"
   229  			log.Entry().Info("SUCCESS")
   230  		},
   231  	}
   232  
   233  	addProtecodeExecuteScanFlags(createProtecodeExecuteScanCmd, &stepConfig)
   234  	return createProtecodeExecuteScanCmd
   235  }
   236  
   237  func addProtecodeExecuteScanFlags(cmd *cobra.Command, stepConfig *protecodeExecuteScanOptions) {
   238  	cmd.Flags().StringVar(&stepConfig.ExcludeCVEs, "excludeCVEs", ``, "DEPRECATED: Do use triaging within the Protecode UI instead")
   239  	cmd.Flags().BoolVar(&stepConfig.FailOnSevereVulnerabilities, "failOnSevereVulnerabilities", true, "Whether to fail the job on severe vulnerabilties or not")
   240  	cmd.Flags().StringVar(&stepConfig.ScanImage, "scanImage", os.Getenv("PIPER_scanImage"), "The reference to the docker image to scan with Protecode. Note: If possible please also check [fetchUrl](https://www.project-piper.io/steps/protecodeExecuteScan/#fetchurl) parameter, which might help you to optimize upload time.")
   241  	cmd.Flags().StringVar(&stepConfig.DockerRegistryURL, "dockerRegistryUrl", os.Getenv("PIPER_dockerRegistryUrl"), "The reference to the docker registry to scan with Protecode")
   242  	cmd.Flags().StringVar(&stepConfig.DockerConfigJSON, "dockerConfigJSON", os.Getenv("PIPER_dockerConfigJSON"), "Path to the file `.docker/config.json` - this is typically provided by your CI/CD system. You can find more details about the Docker credentials in the [Docker documentation](https://docs.docker.com/engine/reference/commandline/login/).")
   243  	cmd.Flags().StringVar(&stepConfig.CleanupMode, "cleanupMode", `binary`, "Decides which parts are removed from the Protecode backend after the scan")
   244  	cmd.Flags().StringVar(&stepConfig.FilePath, "filePath", os.Getenv("PIPER_filePath"), "The path to the file from local workspace to scan with Protecode")
   245  	cmd.Flags().BoolVar(&stepConfig.IncludeLayers, "includeLayers", false, "Flag if the docker layers should be included")
   246  	cmd.Flags().StringVar(&stepConfig.TimeoutMinutes, "timeoutMinutes", `60`, "The timeout to wait for the scan to finish")
   247  	cmd.Flags().StringVar(&stepConfig.ServerURL, "serverUrl", os.Getenv("PIPER_serverUrl"), "The URL to the Protecode backend")
   248  	cmd.Flags().StringVar(&stepConfig.ReportFileName, "reportFileName", `protecode_report.pdf`, "The file name of the report to be created")
   249  	cmd.Flags().StringVar(&stepConfig.FetchURL, "fetchUrl", os.Getenv("PIPER_fetchUrl"), "The URL to fetch the file or image to scan with Protecode.")
   250  	cmd.Flags().StringVar(&stepConfig.Group, "group", os.Getenv("PIPER_group"), "The Protecode group ID of your team")
   251  	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")
   252  	cmd.Flags().IntVar(&stepConfig.ReplaceProductID, "replaceProductId", 0, "Specify <replaceProductId> which application binary will be replaced and rescanned and product id remains unchanged. By using this parameter, Protecode avoids creating multiple same products. Note this will affect results and feeds. If product id is not specified, then Piper starts auto detection mechanism, more precisely it searches a product id with scanned product name in that specified group, if there are several scans have been done with the same product name then the latest scan id will be fetched from BDBA backend. After obtaining product id, Piper re-uploads / replaces new binary without affecting already existing product id.")
   253  	cmd.Flags().StringVar(&stepConfig.Username, "username", os.Getenv("PIPER_username"), "User which is used for the protecode scan")
   254  	cmd.Flags().StringVar(&stepConfig.Password, "password", os.Getenv("PIPER_password"), "Password which is used for the user")
   255  	cmd.Flags().StringVar(&stepConfig.Version, "version", os.Getenv("PIPER_version"), "The version of the artifact to allow identification in protecode backend")
   256  	cmd.Flags().StringVar(&stepConfig.CustomScanVersion, "customScanVersion", os.Getenv("PIPER_customScanVersion"), "A custom version used along with the uploaded scan results.")
   257  	cmd.Flags().StringVar(&stepConfig.VersioningModel, "versioningModel", `major`, "The versioning model used for result reporting (based on the artifact version). Example 1.2.3 using `major` will result in version 1")
   258  	cmd.Flags().StringVar(&stepConfig.PullRequestName, "pullRequestName", os.Getenv("PIPER_pullRequestName"), "The name of the pull request")
   259  
   260  	cmd.MarkFlagRequired("serverUrl")
   261  	cmd.MarkFlagRequired("group")
   262  	cmd.MarkFlagRequired("username")
   263  	cmd.MarkFlagRequired("password")
   264  }
   265  
   266  // retrieve step metadata
   267  func protecodeExecuteScanMetadata() config.StepData {
   268  	var theMetaData = config.StepData{
   269  		Metadata: config.StepMetadata{
   270  			Name:        "protecodeExecuteScan",
   271  			Aliases:     []config.Alias{},
   272  			Description: "Black Duck Binary Analysis (BDBA), previously known as Protecode is an Open Source Vulnerability Scanner that is capable of scanning binaries. It can be used to scan docker images but is supports many other programming languages especially those of the C family.",
   273  		},
   274  		Spec: config.StepSpec{
   275  			Inputs: config.StepInputs{
   276  				Secrets: []config.StepSecrets{
   277  					{Name: "protecodeCredentialsId", Description: "Jenkins 'Username with password' credentials ID containing username and password to authenticate to the Protecode system.", Type: "jenkins"},
   278  					{Name: "dockerConfigJsonCredentialsId", Description: "Jenkins 'Secret file' credentials ID containing Docker config.json (with registry credential(s)). You can create it like explained in [Prerequisites](https://www.project-piper.io/steps/protecodeExecuteScan/#prerequisites).", Type: "jenkins", Aliases: []config.Alias{{Name: "dockerCredentialsId", Deprecated: true}}},
   279  				},
   280  				Parameters: []config.StepParameters{
   281  					{
   282  						Name:        "excludeCVEs",
   283  						ResourceRef: []config.ResourceReference{},
   284  						Scope:       []string{"PARAMETERS", "STAGES", "STEPS"},
   285  						Type:        "string",
   286  						Mandatory:   false,
   287  						Aliases:     []config.Alias{{Name: "protecodeExcludeCVEs"}},
   288  						Default:     ``,
   289  					},
   290  					{
   291  						Name:        "failOnSevereVulnerabilities",
   292  						ResourceRef: []config.ResourceReference{},
   293  						Scope:       []string{"PARAMETERS", "STAGES", "STEPS"},
   294  						Type:        "bool",
   295  						Mandatory:   false,
   296  						Aliases:     []config.Alias{{Name: "protecodeFailOnSevereVulnerabilities"}},
   297  						Default:     true,
   298  					},
   299  					{
   300  						Name: "scanImage",
   301  						ResourceRef: []config.ResourceReference{
   302  							{
   303  								Name:  "commonPipelineEnvironment",
   304  								Param: "container/imageNameTag",
   305  							},
   306  						},
   307  						Scope:     []string{"GENERAL", "PARAMETERS", "STAGES", "STEPS"},
   308  						Type:      "string",
   309  						Mandatory: false,
   310  						Aliases:   []config.Alias{{Name: "dockerImage"}},
   311  						Default:   os.Getenv("PIPER_scanImage"),
   312  					},
   313  					{
   314  						Name: "dockerRegistryUrl",
   315  						ResourceRef: []config.ResourceReference{
   316  							{
   317  								Name:  "commonPipelineEnvironment",
   318  								Param: "container/registryUrl",
   319  							},
   320  						},
   321  						Scope:     []string{"GENERAL", "PARAMETERS", "STAGES", "STEPS"},
   322  						Type:      "string",
   323  						Mandatory: false,
   324  						Aliases:   []config.Alias{},
   325  						Default:   os.Getenv("PIPER_dockerRegistryUrl"),
   326  					},
   327  					{
   328  						Name: "dockerConfigJSON",
   329  						ResourceRef: []config.ResourceReference{
   330  							{
   331  								Name:  "commonPipelineEnvironment",
   332  								Param: "custom/dockerConfigJSON",
   333  							},
   334  
   335  							{
   336  								Name: "dockerConfigJsonCredentialsId",
   337  								Type: "secret",
   338  							},
   339  
   340  							{
   341  								Name:    "dockerConfigFileVaultSecretName",
   342  								Type:    "vaultSecretFile",
   343  								Default: "docker-config",
   344  							},
   345  						},
   346  						Scope:     []string{"PARAMETERS", "STAGES", "STEPS"},
   347  						Type:      "string",
   348  						Mandatory: false,
   349  						Aliases:   []config.Alias{},
   350  						Default:   os.Getenv("PIPER_dockerConfigJSON"),
   351  					},
   352  					{
   353  						Name:        "cleanupMode",
   354  						ResourceRef: []config.ResourceReference{},
   355  						Scope:       []string{"PARAMETERS", "STAGES", "STEPS"},
   356  						Type:        "string",
   357  						Mandatory:   false,
   358  						Aliases:     []config.Alias{},
   359  						Default:     `binary`,
   360  					},
   361  					{
   362  						Name:        "filePath",
   363  						ResourceRef: []config.ResourceReference{},
   364  						Scope:       []string{"PARAMETERS", "STAGES", "STEPS"},
   365  						Type:        "string",
   366  						Mandatory:   false,
   367  						Aliases:     []config.Alias{},
   368  						Default:     os.Getenv("PIPER_filePath"),
   369  					},
   370  					{
   371  						Name:        "includeLayers",
   372  						ResourceRef: []config.ResourceReference{},
   373  						Scope:       []string{"PARAMETERS", "STAGES", "STEPS"},
   374  						Type:        "bool",
   375  						Mandatory:   false,
   376  						Aliases:     []config.Alias{},
   377  						Default:     false,
   378  					},
   379  					{
   380  						Name:        "timeoutMinutes",
   381  						ResourceRef: []config.ResourceReference{},
   382  						Scope:       []string{"PARAMETERS", "STAGES", "STEPS"},
   383  						Type:        "string",
   384  						Mandatory:   false,
   385  						Aliases:     []config.Alias{{Name: "protecodeTimeoutMinutes"}},
   386  						Default:     `60`,
   387  					},
   388  					{
   389  						Name:        "serverUrl",
   390  						ResourceRef: []config.ResourceReference{},
   391  						Scope:       []string{"GENERAL", "PARAMETERS", "STAGES", "STEPS"},
   392  						Type:        "string",
   393  						Mandatory:   true,
   394  						Aliases:     []config.Alias{{Name: "protecodeServerUrl"}},
   395  						Default:     os.Getenv("PIPER_serverUrl"),
   396  					},
   397  					{
   398  						Name:        "reportFileName",
   399  						ResourceRef: []config.ResourceReference{},
   400  						Scope:       []string{"PARAMETERS", "STAGES", "STEPS"},
   401  						Type:        "string",
   402  						Mandatory:   false,
   403  						Aliases:     []config.Alias{},
   404  						Default:     `protecode_report.pdf`,
   405  					},
   406  					{
   407  						Name:        "fetchUrl",
   408  						ResourceRef: []config.ResourceReference{},
   409  						Scope:       []string{"PARAMETERS", "STAGES", "STEPS"},
   410  						Type:        "string",
   411  						Mandatory:   false,
   412  						Aliases:     []config.Alias{},
   413  						Default:     os.Getenv("PIPER_fetchUrl"),
   414  					},
   415  					{
   416  						Name:        "group",
   417  						ResourceRef: []config.ResourceReference{},
   418  						Scope:       []string{"PARAMETERS", "STAGES", "STEPS"},
   419  						Type:        "string",
   420  						Mandatory:   true,
   421  						Aliases:     []config.Alias{{Name: "protecodeGroup"}},
   422  						Default:     os.Getenv("PIPER_group"),
   423  					},
   424  					{
   425  						Name:        "verifyOnly",
   426  						ResourceRef: []config.ResourceReference{},
   427  						Scope:       []string{"PARAMETERS", "STAGES", "STEPS"},
   428  						Type:        "bool",
   429  						Mandatory:   false,
   430  						Aliases:     []config.Alias{{Name: "reuseExisting", Deprecated: true}},
   431  						Default:     false,
   432  					},
   433  					{
   434  						Name:        "replaceProductId",
   435  						ResourceRef: []config.ResourceReference{},
   436  						Scope:       []string{"PARAMETERS", "STAGES", "STEPS"},
   437  						Type:        "int",
   438  						Mandatory:   false,
   439  						Aliases:     []config.Alias{},
   440  						Default:     0,
   441  					},
   442  					{
   443  						Name: "username",
   444  						ResourceRef: []config.ResourceReference{
   445  							{
   446  								Name:  "protecodeCredentialsId",
   447  								Param: "username",
   448  								Type:  "secret",
   449  							},
   450  
   451  							{
   452  								Name:    "protecodeVaultSecretName",
   453  								Type:    "vaultSecret",
   454  								Default: "protecode",
   455  							},
   456  						},
   457  						Scope:     []string{"PARAMETERS", "STAGES", "STEPS"},
   458  						Type:      "string",
   459  						Mandatory: true,
   460  						Aliases:   []config.Alias{{Name: "user", Deprecated: true}},
   461  						Default:   os.Getenv("PIPER_username"),
   462  					},
   463  					{
   464  						Name: "password",
   465  						ResourceRef: []config.ResourceReference{
   466  							{
   467  								Name:  "protecodeCredentialsId",
   468  								Param: "password",
   469  								Type:  "secret",
   470  							},
   471  
   472  							{
   473  								Name:    "protecodeVaultSecretName",
   474  								Type:    "vaultSecret",
   475  								Default: "protecode",
   476  							},
   477  						},
   478  						Scope:     []string{"PARAMETERS", "STAGES", "STEPS"},
   479  						Type:      "string",
   480  						Mandatory: true,
   481  						Aliases:   []config.Alias{},
   482  						Default:   os.Getenv("PIPER_password"),
   483  					},
   484  					{
   485  						Name: "version",
   486  						ResourceRef: []config.ResourceReference{
   487  							{
   488  								Name:  "commonPipelineEnvironment",
   489  								Param: "artifactVersion",
   490  							},
   491  						},
   492  						Scope:     []string{"PARAMETERS", "STAGES", "STEPS"},
   493  						Type:      "string",
   494  						Mandatory: false,
   495  						Aliases:   []config.Alias{{Name: "artifactVersion", Deprecated: true}},
   496  						Default:   os.Getenv("PIPER_version"),
   497  					},
   498  					{
   499  						Name:        "customScanVersion",
   500  						ResourceRef: []config.ResourceReference{},
   501  						Scope:       []string{"GENERAL", "STAGES", "STEPS", "PARAMETERS"},
   502  						Type:        "string",
   503  						Mandatory:   false,
   504  						Aliases:     []config.Alias{},
   505  						Default:     os.Getenv("PIPER_customScanVersion"),
   506  					},
   507  					{
   508  						Name:        "versioningModel",
   509  						ResourceRef: []config.ResourceReference{},
   510  						Scope:       []string{"PARAMETERS", "GENERAL", "STAGES", "STEPS"},
   511  						Type:        "string",
   512  						Mandatory:   false,
   513  						Aliases:     []config.Alias{},
   514  						Default:     `major`,
   515  					},
   516  					{
   517  						Name:        "pullRequestName",
   518  						ResourceRef: []config.ResourceReference{},
   519  						Scope:       []string{"PARAMETERS", "STAGES", "STEPS"},
   520  						Type:        "string",
   521  						Mandatory:   false,
   522  						Aliases:     []config.Alias{},
   523  						Default:     os.Getenv("PIPER_pullRequestName"),
   524  					},
   525  				},
   526  			},
   527  			Outputs: config.StepOutputs{
   528  				Resources: []config.StepResources{
   529  					{
   530  						Name: "influx",
   531  						Type: "influx",
   532  						Parameters: []map[string]interface{}{
   533  							{"name": "step_data", "fields": []map[string]string{{"name": "protecode"}}},
   534  							{"name": "protecode_data", "fields": []map[string]string{{"name": "excluded_vulnerabilities"}, {"name": "historical_vulnerabilities"}, {"name": "major_vulnerabilities"}, {"name": "minor_vulnerabilities"}, {"name": "triaged_vulnerabilities"}, {"name": "vulnerabilities"}}},
   535  						},
   536  					},
   537  					{
   538  						Name: "reports",
   539  						Type: "reports",
   540  						Parameters: []map[string]interface{}{
   541  							{"filePattern": "**/toolrun_protecode_*.json", "type": "protecode"},
   542  							{"type": "protecode"},
   543  							{"filePattern": "**/protecodeExecuteScan.json", "type": "protecode"},
   544  							{"filePattern": "**/protecodescan_vulns.json", "type": "protecode"},
   545  						},
   546  					},
   547  				},
   548  			},
   549  		},
   550  	}
   551  	return theMetaData
   552  }