metadata:
  name: fortifyExecuteScan
  description: This step executes a Fortify scan on the specified project to perform static code analysis and check the source code for security flaws.
  longDescription: |-
    This step executes a Fortify scan on the specified project to perform static code analysis and check the source code for security flaws.

    The Fortify step triggers a scan locally on your Jenkins within a docker container so finally you have to supply a docker image with a Fortify SCA
    and Java plus Maven / Gradle or alternatively Python installed into it for being able to perform any scans.
    !!! hint "Scanning MTA projects"
        Build type `maven` requires a so called aggregator pom which includes all modules to be scanned. If used in a mta-project which includes non-java submodules as maven dependency (e.g. node via frontend-maven-plugin), exclude those by specifying java path explicitly, e.g. `java/**/src/main/java/**/*`.

    Besides triggering a scan the step verifies the results after they have been uploaded and processed by the Fortify SSC. By default the following KPIs are enforced:
    * All issues must be audited from the Corporate Security Requirements folder.
    * All issues must be audited from the Audit All folder.
    * At least one issue per category must be audited from the Spot Checks of Each Category folder.
    * Nothing needs to be audited from the Optional folder.

spec:
  inputs:
    secrets:
      - name: fortifyCredentialsId
        description: Jenkins 'Secret text' credentials ID containing token to authenticate to Fortify SSC.
        type: jenkins
      - name: githubTokenCredentialsId
        description: Jenkins 'Secret text' credentials ID containing token to authenticate to GitHub.
        type: jenkins
    resources:
      - name: commonPipelineEnvironment
        resourceSpec:
          type: piperEnvironment
      - name: buildDescriptor
        type: stash
      - name: deployDescriptor
        type: stash
      - name: tests
        type: stash
      - name: opensourceConfiguration
        type: stash
    params:
      - name: additionalScanParameters
        description: List of additional scan parameters to be used for Fortify sourceanalyzer command execution.
        type: "[]string"
        scope:
          - PARAMETERS
          - STAGES
          - STEPS
      - name: assignees
        description: Defines the assignees for the Github Issue created/updated with the results of the scan as a list of login names.
        scope:
          - PARAMETERS
          - STAGES
          - STEPS
        type: "[]string"
        default: []
      - name: authToken
        type: string
        description: "The FortifyToken to use for authentication"
        scope:
          - PARAMETERS
          - STAGES
          - STEPS
        mandatory: true
        secret: true
        resourceRef:
          - name: fortifyCredentialsId
            type: secret
          - type: vaultSecret
            name: fortifyVaultSecretName
            default: fortify
      - name: buildDescriptorExcludeList
        type: "[]string"
        description: "List of build descriptors and therefore modules to exclude from the scan and assessment activities."
        scope:
          - PARAMETERS
          - STAGES
          - STEPS
        default: ["unit-tests/pom.xml", "integration-tests/pom.xml"]
      - name: customScanVersion
        type: string
        description: Custom version of the Fortify project used as source.
        longDescription: |-
          Defines a custom version for the Fortify scan which deviates from the typical versioning pattern using [`version`](#version) and [`versioningModel`](#versioningModel).
          It allows to set non-numeric versions as well and supersedes the value of [`version`](#version) which is calculated automatically.
          The parameter is also used by other scan steps (e.g. Detect, Sonar, WhiteSource) and thus allows a common custom version across scan tools.
        scope:
          - GENERAL
          - PARAMETERS
          - STAGES
          - STEPS
      - name: githubToken
        description: "GitHub personal access token as per
          https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line"
        scope:
          - GENERAL
          - PARAMETERS
          - STAGES
          - STEPS
        type: string
        secret: true
        aliases:
          - name: access_token
        resourceRef:
          - name: githubTokenCredentialsId
            type: secret
          - type: vaultSecret
            default: github
            name: githubVaultSecretName
      - name: autoCreate
        type: bool
        description:
          "Whether Fortify project and project version shall be implicitly auto created in case they
          cannot be found in the backend"
        scope:
          - PARAMETERS
          - STAGES
          - STEPS
      - name: modulePath
        type: string
        description: "Allows providing the path for the module to scan"
        scope:
          - PARAMETERS
          - STAGES
          - STEPS
        default: "./"
      - name: pythonRequirementsFile
        type: string
        description:
          "The requirements file used in `buildTool: 'pip'` to populate
          the build environment with the necessary dependencies"
        scope:
          - PARAMETERS
          - STAGES
          - STEPS
      - name: autodetectClasspath
        type: bool
        description: "Whether the classpath is automatically determined via build tool i.e. maven or pip or not at all"
        scope:
          - PARAMETERS
          - STAGES
          - STEPS
        default: true
      - name: mustAuditIssueGroups
        type: string
        description: "Comma separated list of issue groups that must be audited completely"
        scope:
          - PARAMETERS
          - STAGES
          - STEPS
        default: "Corporate Security Requirements, Audit All"
      - name: spotAuditIssueGroups
        type: string
        description:
          "Comma separated list of issue groups that are spot checked and for which `spotCheckMinimum`
          audited issues are enforced"
        scope:
          - PARAMETERS
          - STAGES
          - STEPS
        default: "Spot Checks of Each Category"
      - name: pythonRequirementsInstallSuffix
        type: string
        description:
          "The suffix for the command used to install the requirements file in `buildTool: 'pip'` to populate
          the build environment with the necessary dependencies"
        scope:
          - PARAMETERS
          - STAGES
          - STEPS
      - name: pythonVersion
        type: string
        description: "Python version to be used in `buildTool: 'pip'`"
        scope:
          - GENERAL
          - PARAMETERS
          - STAGES
          - STEPS
        default: python3
        possibleValues:
          - python3
          - python2
      - name: uploadResults
        type: bool
        description: "Whether results shall be uploaded or not"
        scope:
          - PARAMETERS
          - STAGES
          - STEPS
        default: true
      - name: version
        aliases:
          - name: fortifyProjectVersion
            deprecated: true
        type: string
        description: Version used in conjunction with [`versioningModel`](#versioningModel) to identify the Fortify project to be created and used for results aggregation.
        longDescription: |-
          Version used in conjunction with [`versioningModel`](#versioningModel) to identify the Fortify project to be created and used for results aggregation.
          This is usually determined automatically based on the information in the buildTool specific build descriptor file.
        scope:
          - GENERAL
          - PARAMETERS
          - STAGES
          - STEPS
        resourceRef:
          - name: commonPipelineEnvironment
            param: artifactVersion
      - name: buildDescriptorFile
        type: string
        conditions:
          - conditionRef: strings-equal
            params:
              - name: buildTool
                value: maven
        description: "Path to the build descriptor file addressing the module/folder to be scanned."
        scope:
          - PARAMETERS
          - STAGES
          - STEPS
        default: ./pom.xml
      - name: buildDescriptorFile
        type: string
        conditions:
          - conditionRef: strings-equal
            params:
              - name: buildTool
                value: pip
        description: "Path to the build descriptor file addressing the module/folder to be scanned."
        scope:
          - PARAMETERS
          - STAGES
          - STEPS
        default: ./setup.py
      - name: buildDescriptorFile
        type: string
        conditions:
          - conditionRef: strings-equal
            params:
              - name: buildTool
                value: gradle
        description: "Path to the build descriptor file addressing the module/folder to be scanned."
        scope:
          - PARAMETERS
          - STAGES
          - STEPS
        default: ./build.gradle
      - name: commitId
        description: "Set the Git commit ID for identifying artifacts throughout the scan."
        resourceRef:
          - name: commonPipelineEnvironment
            param: git/commitId
        scope:
          - PARAMETERS
          - STAGES
          - STEPS
        type: string
      - name: commitMessage
        description: "Set the Git commit message for identifying pull request merges throughout the scan."
        resourceRef:
          - name: commonPipelineEnvironment
            param: git/commitMessage
        scope:
          - PARAMETERS
          - STAGES
          - STEPS
        type: string
      - name: githubApiUrl
        description: "Set the GitHub API URL."
        scope:
          - GENERAL
          - PARAMETERS
          - STAGES
          - STEPS
        type: string
        default: "https://api.github.com"
      - name: owner
        aliases:
          - name: githubOrg
        description: "Set the GitHub organization."
        resourceRef:
          - name: commonPipelineEnvironment
            param: github/owner
        scope:
          - GENERAL
          - PARAMETERS
          - STAGES
          - STEPS
        type: string
      - name: repository
        aliases:
          - name: githubRepo
        description: "Set the GitHub repository."
        resourceRef:
          - name: commonPipelineEnvironment
            param: github/repository
        scope:
          - GENERAL
          - PARAMETERS
          - STAGES
          - STEPS
        type: string
      - name: memory
        type: string
        description: "The amount of memory granted to the translate/scan executions"
        scope:
          - PARAMETERS
          - STAGES
          - STEPS
        default: "-Xmx4G -Xms512M"
      - name: updateRulePack
        type: bool
        description: "Whether the rule pack shall be updated and pulled from Fortify SSC before scanning or not"
        scope:
          - PARAMETERS
          - STAGES
          - STEPS
        default: true
      - name: reportDownloadEndpoint
        aliases:
          - name: fortifyReportDownloadEndpoint
        type: string
        description: "Fortify SSC endpoint for Report downloads"
        scope:
          - GENERAL
          - PARAMETERS
          - STAGES
          - STEPS
        default: "/transfer/reportDownload.html"
      - name: pollingMinutes
        type: int
        description:
          "The number of minutes for which an uploaded FPR artifact''s status is being polled to finish
          queuing/processing, if exceeded polling will be stopped and an error will be thrown"
        scope:
          - PARAMETERS
          - STAGES
          - STEPS
        default: 30
      - name: quickScan
        type: bool
        description:
          "Whether a quick scan should be performed, please consult the related Fortify documentation on
          JAM on the impact of this setting"
        scope:
          - PARAMETERS
          - STAGES
          - STEPS
        default: false
      - name: translate
        type: string
        description:
          "Options for translate phase of Fortify. Most likely, you do not need to set this parameter.
          See src, exclude. If `'src'` and `'exclude'` are set they are automatically used. Technical details:
          It has to be a JSON string of list of maps with required key `'src'`, and optional keys `'exclude'`,
          `'libDirs'`, `'aspnetcore'`, and `'dotNetCoreVersion'`"
        scope:
          - PARAMETERS
          - STAGES
          - STEPS
      - name: src
        type: "[]string"
        description:
          "A list of source directories to scan. Wildcards can be used, e.g., `'src/main/java/**/*'`.
          If `'translate'` is set, this will ignored. The default value for `buildTool: 'maven'` is
          `['**/*.xml', '**/*.html', '**/*.jsp', '**/*.js', '**/src/main/resources/**/*', '**/src/main/java/**/*', '**/src/gen/java/cds/**/*',
          '**/target/main/java/**/*', '**/target/main/resources/**/*', '**/target/generated-sources/**/*']`, for
          `buildTool: 'pip'` it is `['./**/*']`."
        scope:
          - PARAMETERS
          - STAGES
          - STEPS
      - name: exclude
        type: "[]string"
        description:
          "A list of directories/files to be excluded from the scan. Wildcards can be used, e.g.,
          `'**/Test.java'`. If `translate` is set, this will ignored. The default value for `buildTool: 'maven'` is
          `['**/src/test/**/*']`, for `buildTool: 'pip'` it is `['./**/tests/**/*', './**/setup.py']`."
        scope:
          - PARAMETERS
          - STAGES
          - STEPS
      - name: apiEndpoint
        aliases:
          - name: fortifyApiEndpoint
        type: string
        description: "Fortify SSC endpoint used for uploading the scan results and checking the audit state"
        scope:
          - GENERAL
          - PARAMETERS
          - STAGES
          - STEPS
        default: "/api/v1"
      - name: reportType
        type: string
        description: The type of report to be generated
        scope:
          - PARAMETERS
          - STAGES
          - STEPS
        default: "PDF"
      - name: pythonAdditionalPath
        type: "[]string"
        description: "A list of additional paths which can be used in `buildTool: 'pip'` for customization purposes"
        scope:
          - PARAMETERS
          - STAGES
          - STEPS
        default: ["./lib", "."]
        deprecationMessage: this is deprecated
      - name: artifactUrl
        type: string
        description:
          "Path/URL pointing to an additional artifact repository for resolution of additional
          artifacts during the build"
        scope:
          - PARAMETERS
          - STAGES
          - STEPS
      - name: considerSuspicious
        type: bool
        description: "Whether suspicious issues should trigger the check to fail or not"
        scope:
          - PARAMETERS
          - STAGES
          - STEPS
        default: true
      - name: convertToSarif
        type: bool
        description: "Convert the proprietary format of Fortify scan results to the open SARIF standard."
        scope:
          - PARAMETERS
          - STAGES
          - STEPS
        default: true
      - name: fprUploadEndpoint
        aliases:
          - name: fortifyFprUploadEndpoint
        type: string
        description: "Fortify SSC endpoint for FPR uploads"
        scope:
          - GENERAL
          - PARAMETERS
          - STAGES
          - STEPS
        default: "/upload/resultFileUpload.html"
      - name: projectName
        aliases:
          - name: fortifyProjectName
        type: string
        description: "The project used for reporting results in SSC"
        scope:
          - PARAMETERS
          - STAGES
          - STEPS
        default: '{{list .GroupID .ArtifactID | join "-" | trimAll "-"}}'
      - name: reporting
        type: bool
        description: Influences whether a report is generated or not
        scope:
          - PARAMETERS
          - STAGES
          - STEPS
        default: false
      - name: serverUrl
        aliases:
          - name: fortifyServerUrl
          - name: sscUrl
            deprecated: true
        type: string
        description: "Fortify SSC Url to be used for accessing the APIs"
        mandatory: true
        scope:
          - GENERAL
          - PARAMETERS
          - STAGES
          - STEPS
      - name: pullRequestMessageRegexGroup
        type: int
        description: "The group number for extracting the pull request id in `'pullRequestMessageRegex'`"
        scope:
          - PARAMETERS
          - STAGES
          - STEPS
        default: 1
      - name: deltaMinutes
        type: int
        description:
          "The number of minutes for which an uploaded FPR artifact is considered to be recent and
          healthy, if exceeded an error will be thrown"
        scope:
          - PARAMETERS
          - STAGES
          - STEPS
        default: 5
      - name: spotCheckMinimum
        type: int
        description:
          "The minimum number/percentage of issues that must be audited per category in the `Spot Checks of each
          Category` folder to avoid an error being thrown"
        scope:
          - PARAMETERS
          - STAGES
          - STEPS
        default: 1
      - name: spotCheckMinimumUnit
        type: string
        description:
          "The unit for the spotCheckMinimum to apply."
        scope:
          - PARAMETERS
          - STAGES
          - STEPS
        default: 'number'
        possibleValues:
          - number
          - percentage
      - name: spotCheckMaximum
        type: int
        description:
          "The maximum number of issues that must be audited per category in the `Spot Checks of each
          Category` folder to avoid an error being thrown.
          Note that this flag depends on the result of spotCheckMinimum.
          For example if spotCheckMinimum percentage value exceeds spotCheckMaximum then
          spotCheckMaximum will be considerd else spotCheckMinimum is considered.
          If value is less than one, this flag will be ignored."
        scope:
          - PARAMETERS
          - STAGES
          - STEPS
        default: 0
      - name: fprDownloadEndpoint
        aliases:
          - name: fortifyFprDownloadEndpoint
        type: string
        description: "Fortify SSC endpoint for FPR downloads"
        scope:
          - GENERAL
          - PARAMETERS
          - STAGES
          - STEPS
        default: "/download/currentStateFprDownload.html"
      - name: versioningModel
        aliases:
          - name: defaultVersioningModel
            deprecated: true
        type: string
        description:
          "The default project versioning model used for creating the version based on the build descriptor version to report results in SSC, can be one of `'major'`,
          `'major-minor'`, `'semantic'`, `'full'`"
        scope:
          - PARAMETERS
          - GENERAL
          - STAGES
          - STEPS
        default: "major"
        possibleValues:
          - major
          - major-minor
          - semantic
          - full
      - name: pythonInstallCommand
        type: string
        description:
          "Additional install command that can be run when `buildTool: 'pip'`
          is used which allows further customizing the execution environment of the scan"
        scope:
          - PARAMETERS
          - STAGES
          - STEPS
        default: "{{.Pip}} install --user ."
      - name: reportTemplateId
        type: int
        description: "Report template ID to be used for generating the Fortify report"
        scope:
          - PARAMETERS
          - STAGES
          - STEPS
        default: 18
      - name: filterSetTitle
        type: string
        description: "Title of the filter set to use for analysing the results"
        scope:
          - PARAMETERS
          - STAGES
          - STEPS
        default: "SAP"
      - name: pullRequestName
        type: string
        description:
          "The name of the pull request branch which will trigger creation of a new version in Fortify
          SSC based on the master branch version"
        scope:
          - PARAMETERS
          - STAGES
          - STEPS
      - name: pullRequestMessageRegex
        type: string
        description: "Regex used to identify the PR-XXX reference within the merge commit message"
        scope:
          - PARAMETERS
          - STAGES
          - STEPS
        default: '.*Merge pull request #(\\d+) from.*'
      - name: buildTool
        type: string
        description: "Scan type used for the step which can be `'maven'`, `'pip'` or `'gradle'`"
        scope:
          - GENERAL
          - PARAMETERS
          - STAGES
          - STEPS
        default: maven
      # Global maven settings, should be added to all maven steps
      - name: projectSettingsFile
        type: string
        description: Path to the mvn settings file that should be used as project settings file.
        scope:
          - GENERAL
          - STEPS
          - STAGES
          - PARAMETERS
        aliases:
          - name: maven/projectSettingsFile
      - name: globalSettingsFile
        type: string
        description: Path to the mvn settings file that should be used as global settings file.
        scope:
          - GENERAL
          - STEPS
          - STAGES
          - PARAMETERS
        aliases:
          - name: maven/globalSettingsFile
      - name: m2Path
        type: string
        description: Path to the location of the local repository that should be used.
        scope:
          - GENERAL
          - STEPS
          - STAGES
          - PARAMETERS
        aliases:
          - name: maven/m2Path
      - name: verifyOnly
        type: bool
        description: Whether the step shall only apply verification checks or whether it does a full scan and check cycle
        scope:
          - PARAMETERS
          - STAGES
          - STEPS
        default: false
      - name: installArtifacts
        type: bool
        description:
          "If enabled, it will install all artifacts to the local maven repository to make them available before running Fortify.
          This is required if any maven module has dependencies to other modules in the repository and they were not installed before."
        scope:
          - GENERAL
          - STEPS
          - STAGES
          - PARAMETERS
      - name: createResultIssue
        type: bool
        description: Activate creation of a result issue in GitHub.
        longDescription: |
          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 scheduled runs.
        resourceRef:
          - name: commonPipelineEnvironment
            param: custom/isOptimizedAndScheduled
        scope:
          - GENERAL
          - PARAMETERS
          - STAGES
          - STEPS
        default: false
  containers:
    - image: ""
  outputs:
    resources:
      - name: influx
        type: influx
        params:
          - name: step_data
            fields:
              - name: fortify
                type: bool
          - name: fortify_data
            fields:
              - name: projectID
                type: int64
              - name: projectName
              - name: projectVersion
              - name: projectVersionId
                type: int64
              - name: violations
                type: int
              - name: corporateTotal
                type: int
              - name: corporateAudited
                type: int
              - name: auditAllTotal
                type: int
              - name: auditAllAudited
                type: int
              - name: spotChecksTotal
                type: int
              - name: spotChecksAudited
                type: int
              - name: spotChecksGap
                type: int
              - name: suspicious
                type: int
              - name: exploitable
                type: int
              - name: suppressed
                type: int
      - name: reports
        type: reports
        params:
          - filePattern: "**/*.PDF"
            type: fortify
          - filePattern: "**/*.fpr"
            type: fortify
          - filePattern: "**/fortify-scan.*"
            type: fortify
          - filePattern: "**/toolrun_fortify_*.json"
            type: fortify
          - filePattern: "**/piper_fortify_report.json"
            type: fortify
          - filePattern: "**/piper_fortify_report.html"
            type: fortify
