Digital Developer Conference on Data and AI: Essential data science, machine learning, and AI skills and certification Register for free

Create an API to resume and revoke RACF IDs on z/OS

There is a common misunderstanding that z/OS environments need to be isolated within an infrastructure. However, in recent years open source technologies have been used increasingly for cloud development, which has made it possible to integrate and deliver new features faster than ever, and all of these cloud technologies are also available to use on and with z/OS environments.

One particular open source project from Open Mainframe Project, Zowe, is evolving very fast and allows you to easily access APIs that are available in your environment and make use of all other tools for any cloud platform.

This tutorial shows you how to create a Node.js application that exploits a Zowe component to create an API that can be hosted in any cloud environment to resume and revoke user IDs on z/OS. This can be integrated with a web or mobile application, or even a chatbot.

Figure 1 illustrates the architecture that you will build in this tutorial.

Figure 1. Node.js API communicating with the mainframe

NodeJS API communicating with the mainframe

Prerequisites

To complete this tutorial, you will need:

You will learn how to use Node.js modules to create an API, starting with a “Hello World” web server, and then integrate it with Zowe to communicate with your environment.

Estimated time

You should be able to finish this tutorial in about 30 – 45 minutes, depending on your familiarity with application development.

Steps

Here are the steps required to complete this tutorial. All the code provided below can also be found here.

  1. Create the Node.js project
  2. Install the Node.js modules
  3. Create the “Hello World” program
  4. Add your routes
  5. Integrate with Zowe
1

Create the Node.js project

You can initialize your project in the folder where you are creating the Node.js app by using either this command:

npm init --yes

…or this one:

yarn init -y

This should create a JSON file called package.json, which you will use to describe your project. It can include information about licenses, repositories, packages, scripts, etc.

2

Install the Node.js modules

To build this API, you will create an Express server and use the following Node.js modules:

  • Express — helps you build the web server
  • Dotenv — enables you to keep information (like the IP of the LPAR or the user ID) out of your code, which lets you create some environment variables locally
  • @zowe/cli — allows you to interact with the LPAR and issue the Resource Access Control Facility (RACF) commands
  • nodemon — as a local dependency, helps you to be more productive as you save changes and get your server refreshed automatically

To install these dependencies, use the following commands:

npm i express dotenv @zowe/cli
npm i nodemon --save-dev

…or these:

yarn add express dotenv @zowe/cli
yarn add nodemon -D

Note that once you install these dependencies, a folder called node-modules is created; this is where all code related to the node modules is downloaded.

3

Create the “Hello World” program

Start by creating a folder called src where all your code will reside and where you will create your index.js file:

-
|-/node-modules
|-/src
|    |- index.js
|
|-package.json

To use the express module, you need to bring it to your code in a variable. You can give it any name you choose, so let’s use const express = require("express").

Now the functions of express are available to you, so you can create an instance called app that will be your server and will listen on local port 3000.

const express = require('express');

const app = express()

app.listen(3000)

Before you can test it, you will need to add a route: Create a simple route to your localhost where you send back a “Hello World” message to the browser.

There are different HTTP methods that you can use, but to try it on browser you need to use get. The express get method expects at least two parameters. The route is what comes after the address, so if you just use “/” it will accept requests on http://localhost:3000/. This is how you execute a request when a new request is received:

app.get('/',(req,res)=>{
  return res.send("Hello World")
})

The two variables that the function receives are the incoming request and the response. To use the “Hello World,” you only need to send back a string with the words “Hello World”:

Figure 2. Sending “Hello World” string

Sending "Hello World" string

To test it, update your package.json with your dev script:

"scripts": {
    "dev": "nodemon src"
  },

…and then run:

npm run dev

…or:

yarn run dev

Now you can open your browser to see the response that comes back from http://localhost:3000/.

4

Add your routes

To keep things organized and to avoid putting all your code in one file (making it unreadable), you can create a file called routes.js and then move your routes to it.

-
|-/node-modules
|-/src
|    |- index.js
|    |- routes.js
|
|-package.json

In routes.js, you are going to require only the Router module from express, and you will create one route to resume and one to revoke. In the body of this request, they will expect to receive a JSON with the data of the user. For this request we are going to expect only a JSON like this:

{
  "user":"IDNNNNN"
}

These two routes are accessed through post requests, and for the test you will return a JSON with the message that the ID was resumed or revoked:

Figure 3. Response message – resume or revoke

Response message - resume or revoke

Now, in index.js you can replace app.get with app.use to use these routes. And to read JSON in the requests, you also need to use express.json():

const express = require('express');
const routes = require('./routes');

const app = express()

app.use(express.json())
app.use(routes)

app.listen(3000)
5

Integrate with Zowe

To host your Zowe-related code, you should create a folder called controllers and add the functions related to Zowe in ZoweController.js. You should also add onto your root a file called .env to host the mainframe variables:

-
|-/node-modules
|-/src
|    |- index.js
|    |- routes.js
|    |- /controllers
|              |- ZoweController.js
|
|-package.json
|-.env

To use .env, add require('dotenv/config') at the beginning of index.js, and then add the following content to .env:

MF_HOST=NNN.NNN.NNN.NNN
MF_PORT=NNNN
MF_USER=YOURID
MF_PWD=YOURPWD

In ZoweController, import the @zowe/cli and create the profile that you will use for your connections:

const zowe = require('@zowe/cli');
const profile = {
  host: process.env.MF_HOST,
  port: process.env.MF_PORT,
  user: process.env.MF_USER,
  password: process.env.MF_PWD,
  rejectUnauthorized: false,
}

Next, create the resume and revoke functions to export. To enable this, you will use the modules that are available in @zowe/cli.

A really nice feature of VSCode is that it can easily integrate with TypeScript, and the CLI is written in TypeScript. To facilitate your discovery of what is available, Figure 4 illustrates how to create a zOSMF session, how you can easily find the functions, and what is expected on them:

Figure 4. Creating a zOSMF session

Creating a zOSMF session

These functions depend on external components and you need to wait for the feedback from these calls before proceeding with your execution, so you should create async functions.

After you take the user ID from the post request, you need to create the session and then issue the command to return that the user IDs were resumed or revoked.

async (req, res) => {
    const { user } = req.body;
    const session = zowe.ZosmfSession.createBasicZosmfSession(profile);
    const { commandResponse } = zowe.IssueTso.issueTsoCommand(
      session,
      "fb3",
      `ALU ${user} RESUME`
    );
    return res.json({
      status: `ID ${user} RESUMED`,
      commandResponse,
    });

Figure 5. The final controller

The final controller

With the controller ready, you can now update routes.js to require the controller, and update your routes to use the controller functions.

const { Router } = require("express");
const ZoweController = require('./controllers/ZoweController');

const routes = Router();

routes.post("/resume", ZoweController.resume);
routes.post("/revoke", ZoweController.revoke);

module.exports = routes;

Figure 6. Final code

Final code

Summary

A lot of technologies are becoming available every day, so it’s important to keep an open mind if you are going to make use of them. This tutorial has showed you an easy way to use three simple files to integrate your environment using the Zowe modules to create APIs and help administer your user IDs. This API can now be accessed from a web application, a chatbot, or even another service. So go ahead and add more functions that exploit any of the available Zowe modules, work with datasets, other RACF functions, and more. Go ahead and try it out!