Static analysis of code is “par for the course” in modern software development. Catching problems early, before they cause an outage (or outrage! 😡), is paramount.

Tools like SonarQube help software developers and enterprises achieve supreme code quality by continuously inspecting code for potential bugs, security vulnerabilities, and more.

The Challenge

Given the mission-critical nature of z/OS software, we need to be proactive when it comes to code quality and security.

Traditionally, it’s been challenging to integrate z/OS build processes with software development tools like SonarQube. We have mountains of COBOL, PL/I, etc. code written over literal decades… and more is being written/fixed every day.

This is where Zowe CLI shines.

Zowe CLI

Zowe CLI provides the bridge between traditional z/OS development and tools like SonarQube. It’s a command-line interface written in TypeScript for Node.js that allows you to interact with z/OS from a wide array of platforms and build environments. This versatility makes it perfect for scripting your day-to-day z/OS automation and your continuous integration/delivery automation.

Using SonarQube

In order to scan code with SonarQube, you need to “first extract it onto a filesystem”. The SonarQube documentation for COBOL states: “You can use your own tool or an open-source tool”.

Zowe CLI is that tool 😎

Once you have your z/OS code extracted onto a filesystem, you can use the standard SonarScanner utility (or any of the other SonarQube build tool integrations) to scan your code.

How-To

Preparing for the Scan

As the SonarQube documentation states, we need to “first extract it [our code] onto a filesystem”.

In this case, we’ll assume that our code is contained in partitioned data sets on z/OS.

We can retrieve our source using the zowe zos-files command group, with the zowe zos-files download all-members command. The command downloads all members of a partitioned data set and places them in a directory structure that matches the qualifiers:

Downloading all members in “public.jason.cobol”

The single Zowe command is great, but we have multiple data sets with code in different languages.

To download everything, we can write a script… and since we already have Node.js, we’ll write it in JavaScript.

The Script

It’s best if we write a script that’s executable from the command line and that is configurable. This way it’s easy to invoke at our terminals and on our build systems. The zowe zos-files command group requires your TSO username and password, and those values are unique to the user, so we’ll accept them as command-line arguments:

When the script is executed, an args object is created that will contain the arguments passed on the command line. We’ll use this object later when we execute zowe commands.

Next, we need a way to specify the host name and port of our z/OSMF instance (again, needed by Zowe CLI) and the list of data sets we want to scan.

We can have our script read a properties.json file that contains that information:

Example properties contents:

{ "zosmfHost": "your.zosmf.hostname", "zosmfPort": "your.zosmf.port", "src": { "cbl": [ "cobol.dataset1", "cobol.dataset2" ], "cpy": [ "copybook.dataset1", "copybook.dataset2" ], "pli": [ "pli.dataset1", "pli.dataset2" ] } }

The zosmfHost and zosmfPort properties indicate our z/OSMF hostname and port.

The src property allows us to specify the language suffix and the data sets that contain the source. Using the example properties above, the script will download all members in cobol.dataset1 and cobol.dataset1 and give each file an extension of .cbl .

Now it is just a matter of looping through the source data sets provided in the src property and issuing zowe zos-files download all-members for each data set. We’ll also use the language specification ( cbl , cpy , pli ) as the file extensions on the command’s --extension option:

After we configure our properties.json we can run the script at our terminal:

node zowe_download.js --user tsouser --password tsopassword

When it finishes, all of our z/OS source code is now “extracted onto a filesystem” and ready for scanning.

In addition, since we made the script configurable, we can use this on any project with any combination of data sets and languages.

Scanning with SonarScanner

The SonarScanner tool is a CLI that we can use to scan and send our source to SonarQube. Once we have the tool installed, we need to create a sonar-scanner.properties file:

#-----------------------------------------------------------------# # Customize the following properties for your site #-----------------------------------------------------------------# # The SonarQube Host sonar.host.url=http://your.sonarqube.host/ # The Project Identification - the key is generated by the SonarQube # project admin sonar.projectKey=Zowe-CLI-COBOL sonar.projectVersion=1.0.0 sonar.projectName=ZoweCLICOBOL # Source information - NOTE: this assumes that your source is # downloaded into a directory named "zossrc" sonar.sources=./zossrc sonar.cobol.file.suffixes=cbl,cpy sonar.cobol.copy.suffixes=cpy sonar.pli.file.suffixes=pli # To include copybook analysis, you can uncomment and modify the # following to specify the directory where the copy books reside # after download # sonar.cobol.copy.directories=

The sonar-scanner.properties configures the SonarScanner tool with the hostname of your SonarQube instance, the project key to identifying your project to SonarQube, and information about the source files (like file extension suffixes, where the source is located, etc.).

Once we configure our sonar-scanner.properties file, we can scan our source using sonar-scanner at our terminal:

Sample sonar-scanner Output

When the scan completes, we can navigate to the project in the SonarQube web UI and view the results (the output of sonar-scanner will provide the URL):

Sonar Results Overview

Yikes 😳! Looks like we have some work to do:

Next Steps

Now that we can scan our z/OS code using Zowe CLI and SonarQube, we can integrate it into our build pipelines. We won’t go into the details in this post, but you can find a sample Jenkins pipeline at the Zowe CLI samples repository.

You can find a working and configurable example of scanning z/OS code at the Zowe CLI samples repository.

Learn more about Zowe.