Scripting the creation of a custom Zowe client configuration

Gene Johnston
Zowe
Published in
15 min readMay 24, 2024
Automate the creation of a site-specific Zowe client configuration

{Core} A Zowe client configuration is stored in a file named zowe.config.json. That file contains profiles which provide the connection properties and application properties for Open Mainframe Project’s Zowe CLI, Zowe CLI plug-ins, Zowe Explorer, and Zowe Explorer extensions. In this article I describe how you can write a script to create a zowe.config.json file that is customized with your site’s property values.

Motivation for scripted creation of a configuration

To fully appreciate why some consumers want to create their configuration with a script, we must revisit the Zowe V1 release. The only means to create all of your profiles in Zowe V1 was with separate zowe profiles create (or update) commands.

The V1 zowe profiles create command existed to allow a user to create a profile with all of the appropriate properties as arguments, without requiring the user to navigate the internal persistence of the .zowe/profiles directory. Similarly, a user could issue the command zowe profiles update to update a single property. For example:

zowe profiles update zosmf-p yourProfileName -port 12345

Every end user had to run all of the same ‘profiles’ commands. Consumers who wanted to create numerous profiles to represent their site topology would place a sequence of these commands into a script. That script would then be given to every end user to run on their laptops. The procedural difficulties from this process are what gave rise to the simpler hand-off of a configuration stored in a zowe.config.json file during the Zowe V2 release.

When consumers upgraded from Zowe V1 to V2, they found that the ‘profiles’ commands were deprecated. They felt that they were losing their ability to automate their site configuration. Those users now had to correctly edit the JavaScript Object Notation (JSON) format of the new zowe.config.json file, which some found difficult.

Some discovered that the V2 process of having one person create a zowe.config.json file and then share that file with everybody alleviated the need to run an automated script on each laptop. Others remained uncomfortable editing a JSON file.

With support for Zowe V1 scheduled to end in late summer of 2024, a new round of V1 consumers may feel the same culture shock when upgrading to Zowe V2 or Zowe V3. In fact in Zowe V3, the profiles commands are not just deprecated. They are removed. That is why it is an appropriate time to discuss available options and techniques.

If you are upgrading Zowe and still using old V1 profiles, I would be remiss if I did not point out that you can run a single Zowe command (in V2 or V3) to convert your old V1 profiles to the current Zowe configuration. If that is all that you want to achieve, you do not have to write any script. Type the following command, and your V1 profiles will be automatically converted to a new, fully operational, Zowe configuration.

zowe config convert-profiles

Remaining reasons to create a script

For full disclosure, I must admit that I prefer to use the zowe config init command to create a template, then add property values in a text editor, and add more profiles with copy/paste techniques. If a colleague needs the same configuration as me, I just give them a copy of my zowe.config.json file.

I imagine that some consumers might periodically start from scratch on a clean test machine. Perhaps having all of the values contained in a script is easier for them to confirm their property values before running the script to create the configuration that they need. Maybe they just like the use of a script over copying a configuration file to different systems. I do not feel that everybody has to work just like me, so let’s explore the available options.

Scripting in the post-V1 world

The old ‘profiles’ commands are deprecated in V2 and gone in V3. They were just too limited to be able to support the more flexible possibilities in our current configuration.

Nonetheless, I want to correct the misconception that you can no longer create your configuration in a script. You will use different commands to perform similar functionality. You can run Zowe commands to set individual property values within the JSON structure of your zowe.config.json file. You specify a property name by identifying the path through your JSON structure, for example:

profiles.base.properties.rejectUnauthorized

This makes the creation of a profile a bit more verbose, but not necessarily more complex. After all, this path through your zowe.config.json file represents the mainframe deployment that you have specified for your site. You might want a nested configuration in which lower-level profiles inherit properties from parent properties. While you must specify a path that navigates into such a configuration, the new Zowe commands enable you to create and modify far more complex configurations than could be achieved with the old V1 ‘profiles’ commands.

Characteristics of the sample script in this article

Rather than list numerous, individual command examples, I provide a sample script at the end of this article that creates and modifies a configuration for a hypothetical site with specific needs. It covers a number of scenarios. You can repurpose these techniques to fit your site’s deployment of mainframe systems.

The name of the script is mkzoweprofiles. The script uses the zowe config init command to create a template configuration. The zowe config init command creates a relatively flat, un-nested configuration of profiles. mkzoweprofiles then sets properties within that configuration to your site-specific values. If you replace the fake values that I use in the script with real values for your site, mkzoweprofiles works without further modification. It did for my site.

Instead of describing my choices and techniques within the body of this article, I provide such descriptions in comments contained in the script itself. In fact, there are more comments in the script than statements. mkzoweprofiles has no conditional statements, and does not even use any variables. Therefore, mkzoweprofiles should be relatively easy to follow.

Even if you are not interested in writing a script, you may want to skim through the comments. The comments may provide insight into the relationships among different objectives and the actions needed to achieve those objectives.

Summary

The script at the end of this article creates a simple un-nested Zowe client configuration. If that relatively simple configuration works for your site, the script will work for you almost out-of-the-box. Additionally, the techniques demonstrated within the script can be modified to set values in a much more complex configuration that may represent the real-world deployment of mainframe systems at your site.

Finding out more

If you enjoyed this blog checkout more Zowe blogs here. Or, ask a question and join the conversation on the Open Mainframe Project Slack Channel #zowe-cli or #zowe-onboarding. If this is your first time using the Open Mainframe Slack Channel, register here.

Zowe is owned and managed by the Open Mainframe Project, which is a Linux Foundation project.

List of samples

Since we are about to encounter large blocks of code, here are links to each of the samples within this article.

· Linux shell script 🐧
· Windows PowerShell script 🐱‍🏍
· Output from running the script 🏃‍♀️
· The resulting zowe.config.json configuration file 🎫
· Example of a command working after the script ️👷‍

The scripts and the resulting zowe.config.json file are also available in the config_by_os_script folder of the zowe-cli-sample-scripts GitHub repository.

Full disclosure: The scripts were only tested with a pre-release version of V3, but the commands that are used also exist in Zowe V2.

Linux shell script 🐧

This Linux shell script automates the actions outlined in this article and describes each action through detailed comments. You only need Zowe CLI V2 or V3 installed to use the script.

You can also get mkzoweprofiles.sh from GitHub.

Back to: List of samples

#! /bin/sh
# This script can be customized to automatically create a Zowe
# client configuration and populate the profiles in that
# configuration with your site-specific configuration values.
echo "You have started the creation of a custom Zowe client configuration."

# You want to install your desired plugins before later running
# the 'zowe config init' command, because the 'zowe config init'
# command will create template profiles for any installed Zowe plugins.
# For this example, we install the Endevor plugin.
echo "\nInstalling the Endevor plugin for Zowe CLI."
zowe plugins install @broadcom/endevor-for-zowe-cli

# We run the 'zowe config init' command to create a template configuration.
# The 'zowe config init' command prompts the user for host, user, and password.
# It stores those values in the generated template, within your base profile.
#
# A base profile can be used to connect to APIML, or the values of key
# connection properties in a base profile will be used as the default values
# for service profiles which do not contain some of those required properties.
# We use this base profile only for some default values. A base profile for
# APIML comes later in this script. In this example, all of your services are
# on different LPARs, so we do not need a default host name in the base profile.
echo "Creating your initial Zowe client configuration template."
echo "Press ENTER for the upcoming prompt for host name."
echo "This script will set appropriate host names for you.\n"
zowe config init

# The 'zowe config init' command already stored user and password in the
# generated base profile. So, we only add a value for the
# 'rejectUnauthorized' property, which will then be inherited by all other
# service profiles. Setting rejectUnauthorized to false allows any REST
# request to accept a self-signed certificate. You should set this value
# to adhere to your site's security policy.
echo "\nEnabling self-signed certificates."
zowe config set profiles.base.properties.rejectUnauthorized false

# This site uses zosmf on three different LPARs. One for development,
# one for QA, and one for production. Since all 3 LPARs are in the
# same SYSPLEX, they can share the user and password from the
# base profile, which were set by the earlier 'zowe config init' command.
# For each new LPAR, we set the type to "zosmf", set the host name, and
# set the correct port number.

# Create a direct-connection profile for the development LPAR.
echo "Creating a zosmf connection to your development LPAR."
zowe config set profiles.zosmf_dev "{}"
zowe config set profiles.zosmf_dev.type "zosmf"
zowe config set profiles.zosmf_dev.properties.host "YourDevSystem.YourCompany.com"
zowe config set profiles.zosmf_dev.properties.port 1234

# Create a direct-connection profile for the QA LPAR.
echo "Creating a zosmf connection to your QA LPAR."
zowe config set profiles.zosmf_qa "{}"
zowe config set profiles.zosmf_qa.type "zosmf"
zowe config set profiles.zosmf_qa.host "YourQASystem.YourCompany.com"
zowe config set profiles.zosmf_qa.properties.port 5678

# Create a direct-connection profile for the production LPAR.
echo "Creating a zosmf connection to your production LPAR."
zowe config set profiles.zosmf_prod "{}"
zowe config set profiles.zosmf_prod.type "zosmf"
zowe config set profiles.zosmf_prod.host "YourProductionSystem.YourCompany.com"
zowe config set profiles.zosmf_prod.properties.port 9012

# We connect to the development LPAR most often,
# so make it the default zosmf profile
echo "Setting the default zosmf profile to 'zosmf_dev'."
zowe config set defaults.zosmf "zosmf_dev"

# Since we previously created your own zosmf profiles, we no
# longer need the zosmf profile created by 'zowe config init'.
# We now remove that original zosmf profile. To help with that,
# we use the native Linux command named sed (stream editor).
echo "Removing the generic zosmf profile created by 'zowe config init'."
zowe config set profiles.zosmf "{}"
mv zowe.config.json zowe.config.json_to_edit
sed -e '0,/"zosmf":/{/zosmf/d}' zowe.config.json_to_edit > zowe.config.json
rm zowe.config.json_to_edit

# The 'zowe config init' command conveniently creates profiles for
# every CLI plugin that you have installed at the time that you run
# the 'zowe config init' command. Such profiles are not created with
# values specific for your site. We can set those values in this
# script. In our example, the Endevor plugin was installed before we
# ran 'zowe config init'. Below, we make a direct-to-service connection
# to Endevor. Pretend that your Endevor service runs on a separate host
# from your other services, and it requires a user and password that
# are different from those in your SYSPLEX. We do not set the values
# for user and password within this script because we do not want this
# script to contain hard-coded credentials. We will let your first
# Endevor CLI command prompt for those values, and the command will
# automatically store those values in the Secure Credential Store.
echo "Setting properties for your Endevor system."
zowe config set profiles.endevor.properties.host "YourEndevorSystem.YourCompany.com"
zowe config set profiles.endevor.properties.port 1234
zowe config set profiles.endevor.secure '["user", "password"]'

# Also set some properties in the endevor-location profile.
zowe config set profiles.endevor-location.properties.system "YourGreatApp"
zowe config set profiles.endevor-location.properties.subsystem "YourNextFix"
zowe config set profiles.endevor-location.properties.stageNumber "1"

# This site is also experimenting with APIML. We want to connect
# to one zosmf instance through APIML to test your deployment.
# First, we create a new base profile to specifically connect to
# APIML. Again, We do not set user and password values within this script.
# We will let your first CLI command prompt for and store those values.
echo "Creating a base profile for connecting to APIML."
zowe config set profiles.base_apiml "{}"
zowe config set profiles.base_apiml.type "base"
zowe config set profiles.base_apiml.properties.host "YourApimlSystem.YourCompany.com"
zowe config set profiles.base_apiml.properties.port 12345
zowe config set profiles.base_apiml.properties.rejectUnauthorized false
zowe config set profiles.base_apiml.secure '["user", "password"]'

# You need a different zosmf profile with some different properties
# for use with APIML. You do not need host, port, user, and password.
# Those properties are all handled by the 'base_apiml' profile above.
# We do need a new property named 'basePath' which enables APIML to
# route REST requests to the correct endpoint.
echo "Creating a zosmf profile for use with APIML."
zowe config set profiles.zosmf_thru_apiml "{}"
zowe config set profiles.zosmf_thru_apiml.type "zosmf"
zowe config set profiles.zosmf_thru_apiml.properties.basePath "ibmzosmf/api/v1"

# If we wanted to connect through APIML by default, we could set the
# default base profile to your new base_apiml profile. In this example,
# we leave the following assignments commented out because we intend
# to leave the default as the direct-to-service connnection profile named
# zosmf_dev. We set zosmf_dev as the default earlier in this script.
# For a given command, you can instead add the CLI command options
# "--base-profile base_apiml" and "--zosmf-profile zosmf_thru_apiml"
# for any command that your want to route through APIML.
#
# echo "Setting the default base profile to 'base_apiml'"
# echo "and the default zosmf profile to 'zosmf_thru_apiml'"
# zowe config set defaults.base "base_apiml"
# zowe config set defaults.zosmf "zosmf_thru_apiml"

echo "\nYour custom creation of a Zowe client configuration is complete."

Windows PowerShell script 🐱‍🏍

If your site works on Windows instead of Linux, this PowerShell script provides identical functionality. Since Zowe commands are cross-platform, they are unchanged from the Linux script. I did not replicate the detailed comments from the Linux script. This may make it easier to review the full set of actions taken by the script. You can still rely on the comments from the Linux script since the Zowe commands are identical in both scripts.

You can also get mkzoweprofiles.ps1 from GitHub.

Back to: List of samples

Write-Output "You have started the creation of a custom Zowe client configuration."

Write-Output "`nInstalling the Endevor plugin for Zowe CLI."
zowe plugins install @broadcom/endevor-for-zowe-cli

Write-Output "Creating your initial Zowe client configuration template."
Write-Output "Press ENTER for the upcoming prompt for host name."
Write-Output "This script will set appropriate host names for you.`n"
zowe config init

Write-Output "`nEnabling self-signed certificates."
zowe config set profiles.base.properties.rejectUnauthorized false

Write-Output "Creating a zosmf connection to your development LPAR."
zowe config set profiles.zosmf_dev "{}"
zowe config set profiles.zosmf_dev.type "zosmf"
zowe config set profiles.zosmf_dev.properties.host "YourDevSystem.YourCompany.com"
zowe config set profiles.zosmf_dev.properties.port 1234

Write-Output "Creating a zosmf connection to your QA LPAR."
zowe config set profiles.zosmf_qa "{}"
zowe config set profiles.zosmf_qa.type "zosmf"
zowe config set profiles.zosmf_qa.host "YourQASystem.YourCompany.com"
zowe config set profiles.zosmf_qa.properties.port 5678

Write-Output "Creating a zosmf connection to your production LPAR."
zowe config set profiles.zosmf_prod "{}"
zowe config set profiles.zosmf_prod.type "zosmf"
zowe config set profiles.zosmf_prod.host "YourProductionSystem.YourCompany.com"
zowe config set profiles.zosmf_prod.properties.port 9012

Write-Output "Setting the default zosmf profile to 'zosmf_dev'."
zowe config set defaults.zosmf "zosmf_dev"

# Sed is not a native command on Windows. We use the Windows native
# findstr command to achieve the same result as our Linux shell script.
Write-Output "Removing the generic zosmf profile created by 'zowe config init'."
zowe config set profiles.zosmf "{}"
Copy-Item zowe.config.json zowe.config.json_to_edit
findstr /v /L /C:'"zosmf": {}' zowe.config.json_to_edit > zowe.config.json
Remove-Item zowe.config.json_to_edit

Write-Output "Setting properties for your Endevor system."
zowe config set profiles.endevor.properties.host "YourEndevorSystem.YourCompany.com"
zowe config set profiles.endevor.properties.port 1234
zowe config set profiles.endevor.secure '["user", "password"]'
zowe config set profiles.endevor-location.properties.system "YourGreatApp"
zowe config set profiles.endevor-location.properties.subsystem "YourNextFix"
zowe config set profiles.endevor-location.properties.stageNumber "1"

Write-Output "Creating a base profile for connecting to APIML."
zowe config set profiles.base_apiml "{}"
zowe config set profiles.base_apiml.type "base"
zowe config set profiles.base_apiml.properties.host "YourApimlSystem.YourCompany.com"
zowe config set profiles.base_apiml.properties.port 12345
zowe config set profiles.base_apiml.properties.rejectUnauthorized false
zowe config set profiles.base_apiml.secure '["user", "password"]'

Write-Output "Creating a zosmf profile for use with APIML."
zowe config set profiles.zosmf_thru_apiml "{}"
zowe config set profiles.zosmf_thru_apiml.type "zosmf"
zowe config set profiles.zosmf_thru_apiml.properties.basePath "ibmzosmf/api/v1"

# Uncomment the following lines to use your APIML connection by default.
<#
Write-Output "Setting the default base profile to 'base_apiml'"
Write-Output "and the default zosmf profile to 'zosmf_thru_apiml'"
zowe config set defaults.base "base_apiml"
zowe config set defaults.zosmf "zosmf_thru_apiml"
#>

Output from running the script 🏃‍♀️

When you run either the Linux or Windows script, you get the identical output which is shown below.

Note that the warning below about incompatible versions occurred because the script installed a V2 version of the Endevor plug-in with a V3 pre-release version of Zowe CLI. The warning is irrelevant for the purpose of this exercise. Once both Zowe CLI and the Endevor plugin deliver GA V3 versions, the warning will not occur.

Back to: List of samples

$ ./mkzoweprofiles.sh
You have started the creation of a custom Zowe client configuration.

Installing the Endevor plugin for Zowe CLI.
Plug-ins within the Imperative CLI Framework can legitimately gain
control of the zowe CLI application during the execution of every command.
Install 3rd party plug-ins at your own risk.

Registry = https://registry.npmjs.org/

_______________________________________________________________
Installed plugin name = '@broadcom/endevor-for-zowe-cli'

_____ Validation results for plugin '@broadcom/endevor-for-zowe-cli' _____

*** Warning: The version value (^5.0.1) of the plugin's '@zowe/imperative' property is incompatible
with the version value (8.0.0-next.202404191414) of the zowe command's '@zowe/imperative' property.

This plugin has warnings, but its commands and framework overrides will still be available.


Creating your initial Zowe client configuration template.
Press ENTER for the upcoming prompt for host name.
This script will set appropriate host names for you.

Enter host (Host name of service on the mainframe.) - Press ENTER to skip:
Enter user (User name to authenticate to service on the mainframe.) - Press ENTER to skip:
Enter password (Password to authenticate to service on the mainframe.) - Press ENTER to skip:
Saved config template to /home/stduser/ourstuff/proj/mk_profiles_scripts/zowe.config.json

Enabling self-signed certificates.
Creating a zosmf connection to your development LPAR.
Creating a zosmf connection to your QA LPAR.
Creating a zosmf connection to your production LPAR.
Setting the default zosmf profile to 'zosmf_dev'.
Removing the generic zosmf profile created by 'zowe config init'.
Setting properties for your Endevor system.
Creating a base profile for connecting to APIML.
Creating a zosmf profile for use with APIML.

Your custom creation of a Zowe client configuration is complete.

The resulting zowe.config.json configuration file 🎫

When you run the mkzoweprofiles script, it creates a zowe.config.json file (and a zowe.schema.json file). The zowe.config.json file is shown below. You can match up the values in the configuration file with the values set within the script.

You can also get zowe.config.json from GitHub.

Back to: List of samples

{
"$schema": "./zowe.schema.json",
"profiles": {
"tso": {
"type": "tso",
"properties": {
"account": "",
"codePage": "1047",
"logonProcedure": "IZUFPROC"
},
"secure": []
},
"ssh": {
"type": "ssh",
"properties": {
"port": 22
},
"secure": []
},
"endevor": {
"type": "endevor",
"properties": {
"port": 1234,
"protocol": "https",
"host": "YourEndevorSystem.YourCompany.com"
},
"secure": [
"user",
"password"
]
},
"endevor-location": {
"type": "endevor-location",
"properties": {
"instance": "ENDEVOR",
"environment": "DEV",
"system": "YourGreatApp",
"subsystem": "YourNextFix",
"type": "",
"stageNumber": "1",
"maxrc": 8
},
"secure": []
},
"base": {
"type": "base",
"properties": {
"host": "",
"rejectUnauthorized": false
},
"secure": [
"user",
"password"
]
},
"zosmf_dev": {
"type": "zosmf",
"properties": {
"host": "YourDevSystem.YourCompany.com",
"port": 1234
}
},
"zosmf_qa": {
"type": "zosmf",
"host": "YourQASystem.YourCompany.com",
"properties": {
"port": 5678
}
},
"zosmf_prod": {
"type": "zosmf",
"host": "YourProductionSystem.YourCompany.com",
"properties": {
"port": 9012
}
},
"base_apiml": {
"type": "base",
"properties": {
"host": "YourApimlSystem.YourCompany.com",
"port": 12345,
"rejectUnauthorized": false
},
"secure": [
"user",
"password"
]
},
"zosmf_thru_apiml": {
"type": "zosmf",
"properties": {
"basePath": "ibmzosmf/api/v1"
}
}
},
"defaults": {
"zosmf": "zosmf_dev",
"tso": "tso",
"ssh": "ssh",
"endevor": "endevor",
"endevor-location": "endevor-location",
"base": "base"
},
"autoStore": true
}

Example of a command working after the script ️👷‍

If you place valid property values for your site into the mkzoweprofiles script, you can immediately run a Zowe CLI command with no further setup. The following example shows the successful output of a Zowe command immediately after I ran mkzoweprofiles with correct values for my site.

Back to: List of samples


$ zowe zos-files list data-set SYS1.PARMLIB*
SYS1.PARMLIB
SYS1.PARMLIB.ARCHIVE
SYS1.PARMLIB.NEW
SYS1.PARMLIBN

If you enjoyed this blog checkout more Zowe blogs here. Or, ask a question and join the conversation on the Open Mainframe Project Slack Channel #Zowe-help, #Zowe-announcements or #Zowe-onboarding. If this is your first time using the Open Mainframe slack channel register here.

--

--

Gene Johnston
Zowe
Writer for

I am a principal software engineer at Broadcom and a contributor to the Command Line Interface component of the Zowe project.