github.com/xgoffin/jenkins-library@v1.154.0/vars/snykExecute.groovy (about)

     1  import static com.sap.piper.Prerequisites.checkScript
     2  
     3  import com.sap.piper.ConfigurationHelper
     4  import com.sap.piper.GenerateDocumentation
     5  import com.sap.piper.Utils
     6  import com.sap.piper.mta.MtaMultiplexer
     7  import com.sap.piper.MapUtils
     8  
     9  import groovy.transform.Field
    10  
    11  @Field def STEP_NAME = getClass().getName()
    12  
    13  @Field Set GENERAL_CONFIG_KEYS = [
    14      /**
    15       * Credentials for accessing the Snyk API.
    16       * @possibleValues Jenkins credentials id
    17       */
    18      'snykCredentialsId'
    19  ]
    20  @Field Set STEP_CONFIG_KEYS = GENERAL_CONFIG_KEYS.plus([
    21      /**
    22       * The path to the build descriptor file, e.g. `./package.json`.
    23       */
    24      'buildDescriptorFile',
    25      /** @see dockerExecute */
    26      'dockerImage',
    27      /** @see dockerExecute*/
    28      'dockerEnvVars',
    29      /** @see dockerExecute */
    30      'dockerOptions',
    31      /** @see dockerExecute*/
    32      'dockerWorkspace',
    33      /**
    34       * Only scanType 'mta': Exclude modules from MTA projects.
    35       */
    36      'exclude',
    37      /**
    38       * Monitor the application's dependencies for new vulnerabilities.
    39       */
    40      'monitor',
    41      //TODO: move to general
    42      /**
    43       * The type of project that should be scanned.
    44       * @possibleValues `npm`, `mta`
    45       */
    46      'scanType',
    47      /**
    48       * Only needed for `monitor: true`: The organisation ID to determine the organisation to report to.
    49       */
    50      'snykOrg',
    51      /**
    52       * Generate and archive a JSON report.
    53       */
    54      'toJson',
    55      /**
    56       * Generate and archive a HTML report.
    57       */
    58      'toHtml'
    59  ])
    60  @Field Set PARAMETER_KEYS = STEP_CONFIG_KEYS
    61  
    62  //https://snyk.io/docs/continuous-integration/
    63  /**
    64   * This step performs an open source vulnerability scan on a *Node project* or *Node module inside an MTA project* through snyk.io.
    65   */
    66  @GenerateDocumentation
    67  void call(Map parameters = [:]) {
    68      handlePipelineStepErrors(stepName: STEP_NAME, stepParameters: parameters) {
    69          def script = checkScript(this, parameters) ?: this
    70          def utils = parameters.juStabUtils ?: new Utils()
    71          String stageName = parameters.stageName ?: env.STAGE_NAME
    72  
    73          Map config = ConfigurationHelper.newInstance(this)
    74              .loadStepDefaults([:], stageName)
    75              .mixinGeneralConfig(script.commonPipelineEnvironment, GENERAL_CONFIG_KEYS)
    76              .mixinStepConfig(script.commonPipelineEnvironment, STEP_CONFIG_KEYS)
    77              .mixinStageConfig(script.commonPipelineEnvironment, stageName, STEP_CONFIG_KEYS)
    78              .mixin(parameters, PARAMETER_KEYS)
    79              // check mandatory parameters
    80              .withMandatoryProperty('dockerImage')
    81              .withMandatoryProperty('snykCredentialsId')
    82              .use()
    83  
    84          utils.pushToSWA([
    85              step: STEP_NAME,
    86              stepParamKey1: 'scriptMissing',
    87              stepParam1: parameters?.script == null
    88          ], config)
    89  
    90          utils.unstashAll(config.stashContent)
    91  
    92          switch(config.scanType) {
    93              case 'mta':
    94                  def scanJobs = [failFast: false]
    95                  // create job for each package.json with scanType: 'npm'
    96                  scanJobs.putAll(MtaMultiplexer.createJobs(
    97                      this, parameters, config.exclude, 'Snyk', 'package.json', 'npm'
    98                  ){options -> snykExecute(options)})
    99                  // execute scan jobs in parallel
   100                  parallel scanJobs
   101                  break
   102              case 'npm':
   103                  // set default file for scanType
   104                  def path = config.buildDescriptorFile.replace('package.json', '')
   105                  try{
   106                      withCredentials([string(
   107                          credentialsId: config.snykCredentialsId,
   108                          variable: 'token'
   109                      )]) {
   110                          dockerExecute(
   111                              script: script,
   112                              dockerImage: config.dockerImage,
   113                              dockerEnvVars: MapUtils.merge(['SNYK_TOKEN': token],config.dockerEnvVars?:[:]),
   114                              dockerWorkspace: config.dockerWorkspace,
   115                              dockerOptions: config.dockerOptions,
   116                              stashContent: config.stashContent
   117                          ) {
   118                              sh returnStatus: true, script: """
   119                                  node --version
   120                                  npm --version
   121                              """
   122                              // install Snyk
   123                              sh 'npm install snyk --global --quiet'
   124                              if(config.toHtml){
   125                                  config.toJson = true
   126                                  sh 'npm install snyk-to-html --global --quiet'
   127                              }
   128                              // install NPM dependencies
   129                              sh "cd '${path}' && npm install --quiet"
   130                              // execute Snyk scan
   131                              def cmd = []
   132                              cmd.push("cd '${path}'")
   133                              if(config.monitor) {
   134                                  cmd.push('&& snyk monitor')
   135                                  if(config.snykOrg)
   136                                      cmd.push("--org=${config.snykOrg}")
   137                              }
   138                              cmd.push('&& snyk test')
   139                              if(config.toJson)
   140                                  cmd.push("--json > snyk.json")
   141                              try{
   142                                  sh cmd.join(' ')
   143                              }finally{
   144                                  if(config.toHtml) sh "snyk-to-html -i ${path}snyk.json -o ${path}snyk.html"
   145                              }
   146                          }
   147                      }
   148                  }finally{
   149                      if(config.toJson) archiveArtifacts "${path.replaceAll('\\./', '')}snyk.json"
   150                      if(config.toHtml) archiveArtifacts "${path.replaceAll('\\./', '')}snyk.html"
   151                  }
   152                  break
   153              default:
   154                  error "[ERROR][${STEP_NAME}] ScanType '${config.scanType}' not supported!"
   155          }
   156      }
   157  }